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

Adr*_*ian 6 c++ methods shared class

假设我有一个大量存在的对象,存储关于自身的少量数据,但需要几个更大的函数来自行处理.

class Foo
{
public:
    bool is_dead();

private:
    float x, y, z;
    bool dead;
    void check_self();
    void update_self();
    void question_self();
};
Run Code Online (Sandbox Code Playgroud)

我可以从编译器中获得什么样的行为 - 每个新的Foo对象是否会导致其方法的副本被复制到内存中?

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

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

Bas*_*tch 5

C++方法只是简单的函数(其约定this通常成为隐含的​​第一个参数).

函数主要是机器代码,从某个特定地址开始.启动地址是调用该函数所需的全部内容.

所以对象(或它们的vtable)最多需要被调用函数的地址.

当然,函数需要一些位置(在文本段中).

但是对象不需要额外的空间用于该功能.如果该函数不是虚拟的,则每个对象不需要额外的空间.如果该函数是虚拟的,则该对象具有单个 vtable(每个虚拟类).通常,每个对象具有指向vtable的指针作为其第一个字段.这意味着x86-64/Linux上每个对象有8个字节.(假设单个继承)的每个对象具有一个虚表指针,独立的数目或的代码规模的虚拟功能.

如果在多个超类中使用虚方法有多个(可能是虚拟的)继承,则每个实例需要几个vtable指针.

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

如果你添加一个(或几百个)虚函数Foo(那么你应该有一个虚拟析构函数,请参阅C++中的三个规则),每个实例都有一个vtable指针.

如果你想要一个特定于实例的行为(所以实例a并且b可能有不同的行为)而不使用类机制,你需要一些成员函数指针(在C++ 03中)或(在C++ 11中)一些std::function(也许是匿名封闭).当然,他们在每个例子中都需要空间.

顺便说一句,要知道某种类型或类的大小,请使用sizeof....(如果相关,它确实包括vtable [s]指针[s]).