【问题标题】:Are methods duplicated in memory for every instance of an object? If so, can this be avoided?对象的每个实例的方法是否在内存中重复?如果是这样,这可以避免吗?
【发布时间】:2014-09-18 05:11:50
【问题描述】:

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

class Foo
{
public:
    bool is_dead();

private:
    float x, y, z;
    bool dead;
    void check_self();
    void update_self();
    void question_self();
};

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

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

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

【问题讨论】:

  • 不,它们不是重复的。为什么你会有其他想法?会有什么好处? @Arusekk 使用 static 或 const 为什么?
  • 我不得不说我对我的问题收到的反对票(并且可能会自动删除)感到失望。我用谷歌搜索但没有找到任何关于“vtables”的信息。爱好者不会通过阅读关于语言背后基本概念的厚书来接触 C++。他们从简单的例子开始,随着时间的推移消除他们的误解。吸取教训,我以后会坚持使用用户论坛。
  • 说真的,伙计们,你们为什么对这样的事情投反对票?仅仅因为作者可能是通过这些信息来的吗?他有一点,不是每个人都有兴趣阅读语言规范。毕竟,它没有那么有趣。 SO变成了多么不友好的地方。
  • 虽然我没有投反对票,但也许其中一些是因为之前已经提出和回答过这类问题。例如,当谷歌搜索问题标题的第一句话时,第一个结果是stackoverflow.com/questions/648647/…

标签: c++ class methods shared


【解决方案1】:

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

函数大多是机器代码,从某个特定地址开始。调用函数只需要起始地址。

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

当然,函数会占据一些位置(在文本段中)。

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

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

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

如果您向Foo 添加一个(或数百个)虚函数(那么您应该有一个虚析构函数,请参阅rule of three in C++),每个实例都会有一个vtable 指针。

如果您想要特定于实例的行为(因此实例 ab 可能有不同的行为)为此使用类机制,您需要一些成员函数指针 (在 C++03 中)或(在 C++11 中)一些 std::function(可能是匿名的 closures)。当然,它们在每个实例中都需要空间。

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

【讨论】:

  • 我明白了。所以编译器知道 - 与(非静态)成员变量不同 - 方法不需要存储不止一次。谢谢!
【解决方案2】:

方法存在于程序中的每个类,而不是每个对象。 尝试阅读一些有关 c++ 的好书,以了解有关语言的简单事实。

【讨论】:

    猜你喜欢
    • 2015-03-01
    • 2013-09-17
    • 2012-06-10
    • 2016-01-19
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    相关资源
    最近更新 更多