4

可能重复:
为什么类大小仅取决于数据成员而不取决于成员函数?

当我第一次了解继承时,我的老师说与数据成员相反,成员函数不会改变类的大小。也就是说,如果类 B 继承自类 A,那么当且仅当至少添加一个数据成员时,B 的大小才会大于 A 的大小,并且不会根据函数成员的数量而改变。这是对的吗?如果是这样,这个机制是如何工作的?似乎两个成员都应该放在堆中,因此会增加大小。

谢谢你,盖伊

4

3 回答 3

3

成员变量存储为每个类实例的一部分。但成员函数不是。

类的每个实例都必须具有每个成员变量的单独副本。这使每个对象保持唯一。

但是成员函数是代码。而且无论你有多少特定类的实例,绝对没有理由拥有多个代码副本。相同的代码只是对实例数据进行操作。

由于代码不同,因此代码不是类实例大小的一部分。并且sizeof(myClass)不会包括代码占用的字节数。

于 2013-01-15T21:25:54.710 回答
2

您可以想象调用成员函数myClass.myMethod(x)类似于myMethod(myClass, x). 每个类的每个实例都不需要该函数。您可以使用关键字访问此“隐藏”的第一个参数this

于 2013-01-15T21:30:16.067 回答
1

如果类 B 继承自类 A,则当且仅当添加至少一个数据成员时,B 的大小将大于 A 的大小,并且不会根据函数成员的数量进行更改。

是的,它是正确的。(如果 B 没有实现其他方法)。每个类实例都有一个数据成员的副本和一个指向实际存储它们的成员函数表的指针。

成员函数的代码在同一类的不同实例之间共享。如果 B 不覆盖基类 A 的任何成员函数,则 A 和 B 可以共享相同的方法。当您覆盖子类中的成员函数时,基本上您正在更改此机制,创建被覆盖成员函数的新定义,仅适用于您定义它的子类(es.B)。

通常,成员函数在编译时绑定。因此,如果您有一个通过指向基类 A 的指针引用的子类 B 的实例,并且您调用在两个类中定义的成员函数 foo(),则调用的函数将是在基类中实现的函数。您可以在运行时强制绑定成员函数,将其声明为虚拟(调用的成员函数将是通过基指针指向的类的实际类型之一)。这将导致一个额外的表(虚拟方法表,vtable)用于存储虚拟方法,以及每次调用的双指针间接。

于 2013-01-15T21:27:15.553 回答