假设我有一个大量存在的对象,存储关于自身的少量数据,但需要几个较大的函数来自行处理。
class Foo
{
public:
bool is_dead();
private:
float x, y, z;
bool dead;
void check_self();
void update_self();
void question_self();
};
我可以从编译器中得到什么样的行为 - 每个新的Foo对象都会导致其方法的副本被复制到内存中吗?
如果是,那么在避免重复的同时管理特定于类的(类似私有)函数有什么好的选择?
如果没有,你能详细说明一下吗?
答案 0 :(得分:5)
C ++方法只是函数(约会this
,它通常成为隐含的第一个参数)。
函数主要是机器代码,从某个特定地址开始。只需要起始地址即可调用该函数。
所以对象(或它们的vtable)最多需要被调用函数的地址。
当然,某个功能需要一些地方(在文本段中)。
但是对象不需要额外的空间用于该功能。如果该函数不是虚拟的,则不需要额外的空间每个对象。如果该函数是虚函数,则该对象具有单 vtable(每个虚拟类)。通常,每个对象具有指向vtable的指针作为其第一个字段。这意味着x86-64 / Linux上每个对象有8个字节。每个对象(假设单个继承)都有一个vtable指针,与virtual functions的数量或代码大小无关。
如果您在多个超类中使用虚方法进行多次(可能是虚拟的)继承,则每个实例需要几个vtable指针。
因此,对于Foo
示例,没有virtual
函数(并且没有包含其中一些的超类),因此Foo
的实例不包含vtable指针。
如果向Foo
添加一个(或几百个)虚函数(那么你应该有一个虚拟析构函数,请参阅rule of three in C++),每个实例都有一个vtable指针。
如果您希望某个行为特定于实例(因此实例a
和b
可能有不同的行为)没有使用类机制,那么您需要一些成员函数指针(在C ++ 03中)或(在C++11中)一些std::function
(可能是匿名closures)。当然,他们在每个场合都需要空间。
BTW,要知道某个类型或类的大小,请使用sizeof
....(如果相关,它确实包括vtable [s]指针[s]。)
答案 1 :(得分:0)
程序中的每个类都存在方法,而不是每个对象。 尝试阅读一些关于c ++的好书,以便了解有关语言的简单事实。