每个对象的实例都在内存中重复方法吗?如果是这样,这是可以避免的吗?

Are methods duplicated in memory for every instance of an object? If so, can this be avoided?

本文关键字:如果 可以避免 方法 实例 对象 内存      更新时间:2023-10-16

假设我有一个大量存在的对象,它本身存储的数据很少,但需要几个较大的函数来作用于它。

class Foo
{
public:
    bool is_dead();
private:
    float x, y, z;
    bool dead;
    void check_self();
    void update_self();
    void question_self();
};

我可以期待编译器的什么行为-每个新的Foo对象都会导致其方法的副本被复制到内存中吗?

如果是,在避免重复的同时管理类特定的(private-like)函数有什么好的选择?

如果没有,你能详细说明一下吗?

c++方法是简单的函数(有一个关于this的约定,它经常成为隐式的第一个参数)。

函数大多是机器码,从某个特定地址开始。起始地址是调用函数所需要的全部内容。

所以对象(或它们的虚函数表)最多只需要调用函数的地址。

当然,函数会出现在某个位置(在文本段中)。

但是对象不需要为该函数提供额外的空间。如果函数不是虚函数,则每个对象不需要额外的空间。如果函数是虚函数,则对象有一个单个虚函数表(每个虚类)。通常,每个对象的第一个字段是指向虚函数表的指针。这意味着在x86-64/Linux上每个对象8个字节。每个对象(假设单一继承)都有一个虚函数表指针,与虚函数的编号或代码大小无关功能。

如果在多个超类中有多个虚方法的多重(可能是虚)继承,则每个实例需要几个虚表指针。

因此,对于您的Foo示例,没有virtual函数(并且没有包含其中一些的超类),因此Foo的实例不包含虚表指针。

如果向Foo添加一个(或数百个)虚函数(那么你应该有一个虚析构函数,参见c++中的三规则),每个实例将有一个虚表指针。

如果您希望行为特定于实例(因此实例ab可能具有不同的行为)而不使用类机制,则需要一些成员函数指针(在c++ 03中)或(在c++ 11中)一些std::function(可能是匿名闭包)。当然,它们在任何情况下都需要空间。

顺便说一句,要知道某些类型或类的大小,请使用sizeof ....

方法存在于程序中的每个类,但不是每个对象。试着读一些关于c++的好书来了解这么简单的语言知识。