c++ - 有没有办法防止在 C++ 中发出 vtable?

标签 c++

我正在创建一个库,它要求类必须继承其他类才能执行特定的操作。然而,这并不是简单的多态性。这些类是虚函数的代码生成器,没有数据,并且依赖于 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/

相关文章:

c++ - 为什么键入三个非整数会导致此函数无限递归?

C++模板类编译错误

c++ - 在 C++ 中,是否允许将函数指针转换为一个函数指针,该函数指针作为参数获取一个指向基类或派生类的指针?

c++ - 是否有标志使 istream 仅将制表符视为分隔符?

c++ - CUDA、NPP 滤波器

c++ - 数组的值随机变化

c++ - 将文件读入Qt

android - 无法解决 fullPathForFilename : Possible missing file error in cocos2dx

c++ - C++密码问题

c++ - 如果我将一个大函数声明为内联函数怎么办?