【问题标题】:How do static member variables affect object size?静态成员变量如何影响对象大小?
【发布时间】:2011-01-09 18:39:31
【问题描述】:

我想知道静态成员变量通常如何在 C++ 等语言中实现,以及它们的使用是否会影响实例化对象的大小。

我知道静态成员由该类的所有实例共享,但它是如何共享的?如果它影响对象大小,那么拥有 10 个静态变量会增加比 1 更多的大小吗?

我之所以这么问,是因为我可以想到两种可能的实现方式:

  • 向每个对象添加指向静态数据的指针,类似于某些实现添加指向虚函数表的指针的方式
  • 静态数据只是像全局变量一样被直接引用,偏移量由链接器/加载器解析

【问题讨论】:

标签: c++ static-members


【解决方案1】:

在 C++ 中,静态成员不属于类的实例。它们甚至不会增加实例和类的大小 1 位!

struct A
{
    int i;
    static int j;
};
struct B
{
    int i;
};
std::cout << (sizeof(A) == sizeof(B)) << std::endl;

输出:

1

AB 的大小完全相同。静态成员更像是通过A::j 访问的全局对象。

在 ideone 上查看演示:http://www.ideone.com/YeYxe


$9.4.2/1 来自 C++ 标准 (2003),

静态数据成员不属于 一个类的子对象。 有 只有一个静态数据成员的副本 由所有对象共享 类。

标准版 9.4.2/3 美元和 7 美元,

一旦静态数据成员被 已定义,即使没有对象也存在 已经创建了它的类。

静态数据成员被初始化 并像非本地一样被销毁 对象(3.6.2、3.6.3)。

正如我所说,静态成员更像是全局对象!

【讨论】:

  • @Nawaz:很有趣。因此,如果我们想要序列化 ​​A,我们不能仅仅假设必要的内存是 sizeof(A) 的结果。对?那我们怎么知道真正的大小呢?
  • 静态变量不是对象本身的一部分,不应该像它一样被序列化。
  • @Nerian :序列化还取决于您希望在序列化对象中包含哪些成员,以及不包含哪些成员。由于静态成员不属于类的 instances,那么很可能您也不想序列化它;它们更像是使用A::j 访问的全局对象。无论如何,不​​要相信我的意见。我对序列化了解不多。问问知道的人。并开始另一个话题。 :-)
  • +1:对于 ideone.com 的链接,我第一次看到它。很酷!
  • @Robert 这可以从POD类型的定义中推断出来;标准小心地指出,添加static 成员不能将 POD 类型转换为非 POD 类型。并且POD类型的内存布局是严格定义的。
【解决方案2】:

静态成员在编译时由编译器解析。在许多方面,静态变量与引擎盖下的全局变量没有什么不同。区别仅在于您在代码中引用它们的方式、它们可见的范围以及它们被初始化的方式和时间。

【讨论】:

  • 您能否添加一个参考资料链接,以进一步解释您的答案?
  • @David:我当然不是 Vinay,但我不确定什么样的参考资料可以解决这个问题。我认为 Vinay 的答案最好分别得到 C++ 和 Java 语言规范中的 not 的支持:定义中没有任何内容表明静态变量 对类施加运行时开销实例;因此,他们没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 2021-09-18
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多