具有虚函数的紧类 我在一个讨论中被问到在C++类中添加虚拟函数是什么意思。我说,一个缺点是类的对象有一个指针指向它的虚拟表,对于一个小C++类,它在64位平台上增加了8字节。如果一个人创建了数百万这样的类实例,增加了程序的内存消耗 < >但是,为什么C++中没有一个指向虚拟表的微小指针或者一个虚拟表的小指针或者一个虚拟表的紧凑指针。像这样的事情: class [[compact]] base { ~base(){} virtual f() = 0; }; class [[tiny]] another_base { ~base(){} virtual g() = 0; }; class [[small]] yet_another_base { ~base(){} virtual h() = 0; }; class child : public base { virtual f(); }; class user_type : public another_base { ~base(){} virtual g(); };

具有虚函数的紧类 我在一个讨论中被问到在C++类中添加虚拟函数是什么意思。我说,一个缺点是类的对象有一个指针指向它的虚拟表,对于一个小C++类,它在64位平台上增加了8字节。如果一个人创建了数百万这样的类实例,增加了程序的内存消耗 < >但是,为什么C++中没有一个指向虚拟表的微小指针或者一个虚拟表的小指针或者一个虚拟表的紧凑指针。像这样的事情: class [[compact]] base { ~base(){} virtual f() = 0; }; class [[tiny]] another_base { ~base(){} virtual g() = 0; }; class [[small]] yet_another_base { ~base(){} virtual h() = 0; }; class child : public base { virtual f(); }; class user_type : public another_base { ~base(){} virtual g(); };,c++,c++11,C++,C++11,想象一下,我将创建大量的user\u type(事实上,我曾经在一个真实的程序中遇到过这种情况)。默认情况下,编译器创建大小为8(64位)的user\u type实例。但仅使用[[tiny]]属性时,它可能只有1个字节,而使用[[compact]]时可能只有4个字节 此功能是否已可用?如果不是的话,在我看来是有可能实施的。比如在程序中隐藏tiny_vptr和compact_vptr,并在需要查找vtable的实际指针时向其添加第一个字节或前四个字节。例如,在一个程序中,它只允许有256个[[小类

想象一下,我将创建大量的
user\u type
(事实上,我曾经在一个真实的程序中遇到过这种情况)。默认情况下,编译器创建大小为8(64位)的
user\u type
实例。但仅使用[[tiny]]属性时,它可能只有1个字节,而使用[[compact]]时可能只有4个字节


此功能是否已可用?如果不是的话,在我看来是有可能实施的。比如在程序中隐藏
tiny_vptr
compact_vptr
,并在需要查找vtable的实际指针时向其添加第一个字节或前四个字节。例如,在一个程序中,它只允许有256个[[小类]]或65000个[[小类]]类。这就像是在最大速度和节省内存之间进行选择。

没有这样的功能

现在,C++的VTAT特性(至少使用的部分)可以在C或C++中模拟,只具有一点语法糖。

struct my_vtable {
  void(*dtor)(void*) = 0;
  void(*print)(void*) = 0;
  void(*add)(void*, int) = 0;
};

struct my_interface {
  my_vtable const* vtable = 0;
  ~my_interface() { vtable->dtor(this); }
  void print() { vtable->print(this); }
  void add(int x) { vtable->add(this, x); }
};
这需要更多的工作才能使构造函数和析构函数级联工作,虚拟继承有点麻烦,从多重继承构建复合vtable也是一项工作(特别是如果您希望它干净的话)

但是你有工具

使用这些工具,您可以实现
[[tiny]]
vtable功能

现在,如果您关心这一点,一个更好的方法可能是使用代理对象,您可以在实例中存储的任意状态上使用任意函数查找表。将状态存储在实例中,将表存储在其他位置

C++的对象系统并不是那么灵活。它实现了一种安排继承和面向对象的方法。还有许多其他有用的东西,从布局改变到功能更改(例如,C++不支持为类实例建立一次性VTABLE,或者动态创建新类型)。
< >将C++继承系统视为编写OO代码的许多方法之一。知道你应该有一个很好的理由来回避它,并使所得代码尽可能干净,但是不要害怕因为继承关系而不使用C++继承。< / P>如果它被实现,如果派生类的第一个成员是1字节对齐,它只会保存内存。(否则,vtable指针和第一个成员之间会有填充字节)。我想您可以强制将派生类紧密打包,这样就不会有填充字节,但这样您就进入了一个奇怪的特定于域的领域。虚拟函数的真正危害不是因为vptr,而是因为它们的非内联性。@SergeyA:OP问的是关于节省内存的问题。非内联性并不是真正的问题请注意。@Cornstales,不要争辩。然而,OP在实际本质上是错误的,它试图解决不存在的问题,而主要问题仍然没有解决。@Cornstales,同意。但是使用4字节ptr的[[compact]]是可以的,即使派生类有int这样的第一个成员。