我正在创建一个库,它要求类必须继承其他类才能执行特定的操作。然而,这并不是简单的多态性。这些类是虚函数的代码生成器,没有数据,并且依赖于 CRTP,因此它们本身不需要 vtable。
有没有办法阻止为这些类发出 vtable?我假设虚拟函数指针将传递给派生类,并且虚拟析构函数将跳过这些类。有点像将各个类合并为一个。
如果整个 C++ 领域没有通用的东西,那么也许特定于 clang、gcc 和 vc?
示例:
#include<iostream>
template <typename D, typename B>
struct jelly : B
{
virtual void do_stuff() { static_cast<D*>(this)->D::do_some_other_stuff(); }
};
template <typename D>
struct jelly<D, void>
{
virtual void do_stuff() { static_cast<D*>(this)->D::do_some_other_stuff(); }
};
struct A : jelly<A, void>
{
void do_some_other_stuff() { std::cout << "A::do_some_other_stuff()\n"; }
};
struct B : jelly<B, A>
{
void do_some_other_stuff() { std::cout << "B::do_some_other_stuff()\n"; }
};
int main()
{
A a;
a.do_stuff(); // output: A::do_some_other_stuff()
B b;
b.do_stuff(); // output: B::do_some_other_stuff()
A& aa = b;
aa.do_stuff(); // output: B::do_some_other_stuff()
}
澄清一下,这只是一个例子。它确实运行了,但是 jelly
代表的类的数量实际上是 3 个不同的类。一个是由开发人员使用 jelly 库显式继承的,另外两个是在继承回开发人员自己的类之前隐式完成的。正是因为类(class)数量会增加 3 倍,我才开始担心,这也是我问这个问题的原因。
最佳答案
据我所知,唯一可以执行此操作的编译器扩展是 MSVC 的 __declspec(novtable)
:
This form of
__declspec
can be applied to any class declaration, but should only be applied to pure interface classes, that is, classes that will never be instantiated on their own. The__declspec
stops the compiler from generating code to initialize the vfptr in the constructor(s) and destructor of the class. In many cases, this removes the only references to the vtable that are associated with the class and, thus, the linker will remove it. Using this form of__declspec
can result in a significant reduction in code size.If you attempt to instantiate a class marked with
novtable
and then access a class member, you will receive an access violation (AV).
当您使用 MSVC 的 __interface
时,隐含此修饰符。关键字。
关于c++ - 有没有办法防止在 C++ 中发出 vtable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55670116/