Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 非内联非虚拟方法向类实例添加多少字节?C++;_C++_Memory_Vtable - Fatal编程技术网

C++ 非内联非虚拟方法向类实例添加多少字节?C++;

C++ 非内联非虚拟方法向类实例添加多少字节?C++;,c++,memory,vtable,C++,Memory,Vtable,以这两个类为例。(C++) B2类在内存中比B1类大多少 我觉得这是两个答案之一 每个方法32位系统上的单个4字节int指针 或者类似于虚拟方法表的情况 其中会有一个4字节的int指针,指向每个类的一个表,这样它就可以查找它的方法,这是有意义的,但我不知道这种情况是否发生在非虚方法上 谢谢 编辑:感谢所有精彩而快速的回复:)(也有标记的答案)无。 非虚拟方法不会增加类的大小 至于virtual方法,只有添加到类中的第一个方法会增加其大小,所有后续方法都不会 它是否是内联的这一事实也不会影响类的大

以这两个类为例。(C++)

B2类在内存中比B1类大多少

我觉得这是两个答案之一

每个方法32位系统上的单个4字节int指针

或者类似于虚拟方法表的情况

其中会有一个4字节的int指针,指向每个类的一个表,这样它就可以查找它的方法,这是有意义的,但我不知道这种情况是否发生在非虚方法上

谢谢

编辑:感谢所有精彩而快速的回复:)(也有标记的答案)

无。

非虚拟方法不会增加类的大小

至于
virtual
方法,只有添加到类中的第一个方法会增加其大小,所有后续方法都不会

它是否是内联的这一事实也不会影响类的大小

原因是不需要额外的内存。想象一下,如果所有类的所有实例都持有指向该类和所有父类中所有方法的指针。那将是对记忆的巨大浪费

B2 b;
b.f0();
编译器只需生成代码来调用
B2::f0()
指针作为under-The-hood参数传递,以便方法知道要在类的哪个实例上操作

对于一个简单的测试:

class B1 {
public:

};

class B2 {
public:
  void f0 () {}
  void f1 () {}
};

//...
assert( sizeof(B1) == sizeof(B2) );

卢钦的回答是正确的。我只想补充一点,代码保存在文本段上,这与数据所在的位置(数据段)不同。因此,方法影响对象大小的唯一时间是当它们是虚拟方法时,因此强制将vptr放置在对象内部。阅读此文以获得关于分段部分的更多启发:

一个简单的技巧:在编译器中测试它,看看你是否可以伪造你的假设。请注意,即使你尝试了它,并且你的假设没有伪造你的假设,也不意味着你的假设是有效的。可能的重复(由于找到了它,请记为)在C++中,你如何证明这是真的,为什么会这样?@ McMordMaID我已经解释了为什么会这样:1)不需要它,因为方法不需要动态绑定(比如在虚拟方法的情况下)2)巨大的内存浪费。为了证明这一点,您可以比较两个类的大小。添加一个方法并使用sizeof计算前后大小。在您编辑之前,我捕获了您的答复。感谢McMuldMID:我不确定这个行为实际上是标准所要求的,因为它(据说)可以实现C++解释程序。但是,在所有实际实现中(因此,在所有流行的编译器中),方法地址在编译时由编译器硬编码,并且在运行时不需要查找/访问/计算,因此不需要存储指针来查找地址。由于这不是答案,我建议您对此进行注释。不错的链接,顺便说一句!这是一个很好的参考,它似乎完全涵盖了这个问题,足以将这个问题标记为一个傻瓜。
class B1 {
public:

};

class B2 {
public:
  void f0 () {}
  void f1 () {}
};

//...
assert( sizeof(B1) == sizeof(B2) );