【问题标题】:How does a class know the sizeof its members?类如何知道其成员的大小?
【发布时间】:2016-01-03 00:14:59
【问题描述】:

为了跳过这里的一些重复并将问题缩小到更具体的范围,我将很快介绍我认为我理解的内容。

类是指向不同大小变量的指针,称为成员。如果成员大小不同,则都分配到最大成员大小的相同空间。

所以在内存中它们的大小都是相同的,因此我的问题是:一个类如何知道其成员的大小?

例子:

class foo
{
    short a = 99;
    int b = 88;
};

int main()
{
    foo f;

    for (int i = 0; i < sizeof(f); i++)
        cout << (int)((char*)&f)[i] << " ";

    return 0;
}

// Output:
// 99 0 -1 70 88 0 0 0
// 
// where -1 and 70 are random bytes in memory

恭喜那些不明白的人我的主要问题:f如何知道在阅读成员a时如何返回short (99 0) 而不是 int (99 0 -1 70)?

【问题讨论】:

  • 类不是指针,后面的内容没有意义。你似乎混淆了类和联合。
  • 停止投射。如果您知道自己在做什么,而您显然不知道,那就够棘手了。您所做的是未定义的行为,您无法从输出中推断出任何内容。

标签: c++ class pointers sizeof member


【解决方案1】:

类不需要知道,你的编译器知道。

如果成员的大小不同,则都分配给最大成员大小的相同空间。

这根本不是真的。想象一个有两个成员的类,第一个是 20 个双精度的大结构,第二个是一个单字符。

【讨论】:

    【解决方案2】:

    这是编译器的任务,这就是为什么在这种情况和类似情况下类必须是完整类型的原因,即编译器需要这样:

    struct foo {
         short f;
         int b;
    };
    

    ...或类似的。当类型完成时,编译器可以决定类型的大小和它的字段的偏移量以及在某些情况下它需要知道的其他事情。

    如果没有完整的类型定义,它将无法:

    1. 接受foo 类型变量的声明(即foo f; 语句)。
    2. 接受sizeof(foo) 表达式
    3. 创建指向成员的指针。
    4. ...等等。

    由于您无法在没有完整类型的情况下声明变量 f,您将无法获取它的大小或访问它的成员。

    如果你使用了不完整的类型。那是编译器只见过:

    struct foo;
    

    然后编译器不能做任何需要完整类型的事情,但它可以拥有指向foo 的指针,但它不能查看它的内部、分配它或对其进行指针运算。

    【讨论】:

    • 感谢您提供完整而详细的答案,并提供干净的示例。我明白了。
    【解决方案3】:

    你有一些误解,但为了更好地理解你可能会尝试的一件事是在一些简单的结构上使用来自&lt;stddef.h&gt;offsetof( typename, membername ) 宏。也许尝试打印offsetof( foo, a )offsetof( foo, b )(uintptr_t)&amp;f(uintptr_t)&amp;f.b 以查看编译器如何在给定f 的地址的情况下找到f.b。在类方法中,f 被命名为 this

    类的工作方式是这样的(另外,它们还有一个指向它们的虚函数的指针表,当你调用一个时,你实际上是在调用该表中的第一个、第二个或第三个函数)。单继承的工作方式是所有基类的成员和方法首先出现在派生类中,在相同的偏移量处。多重继承的工作方式——很复杂。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 2015-08-07
      • 2012-04-04
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多