一个班级如何知道其成员的规模?

时间:2015-10-06 07:11:59

标签: c++ class pointers sizeof member

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

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

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

示例:

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 如何返回 (99 0)而不是 int (99 0 -1 70)?

3 个答案:

答案 0 :(得分:2)

该类不需要知道,您的编译器会这样做。

  

如果成员的大小不同,他们都被分配了与最大成员相同的空间。

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

答案 1 :(得分:1)

这对编译器来说是一个任务,这就是为什么类必须是这个和类似情况下的完整类型,这就是编译器需要这个:

struct foo {
     short f;
     int b;
};

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

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

  1. 接受foo类型变量的声明(即foo f;语句)。
  2. 接受sizeof(foo)表达式
  3. 创建指向成员的指针。
  4. ......等等。
  5. 由于您无法在没有完整类型的情况下声明变量f,因此您无法获得其大小或访问其成员。

    如果在另一侧,则使用不完整的类型。那是编译器唯一看到的:

    struct foo;
    

    然后编译器不能做任何需要完整类型的事情,但它可以有例如foo的指针,但它不能查看它,分配它或在它上面做指针算术。

答案 2 :(得分:0)

You have some misconceptions, but one thing you might try in order to get a better understanding is to use the offsetof( typename, membername ) macro from <stddef.h> on some simple structs. Maybe try printing offsetof( foo, a ), offsetof( foo, b ), (uintptr_t)&f and (uintptr_t)&f.b to see how the compiler is finding f.b given an address for f. In a class method, f is named this.

The way a class works is like that (plus they also have a table of pointers to their virtual functions, and when you call one, you’re really calling the first, second or third function in that table). The way single inheritance works is that all the base class’ members and methods appear first, at the same offsets, in the derived class. The way multiple inheritance works—is complicated.