一个类如何知道其成员的大小?
How does a class know the sizeof its members?
为了跳过这里的重复,将问题缩小到更具体的范围,我将非常快速地介绍一下我认为我理解的内容。
类是指向不同大小的变量(称为成员)的指针。如果成员大小不同,则按最大成员的大小分配相同的空间。
所以在内存中它们都是相同的大小,因此我的问题:一个类如何知道其成员的大小?
的例子:
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)?
类不需要知道,编译器需要知道。
如果成员大小不同,则按最大成员的大小分配相同的空间。
这是不正确的。想象一个有两个成员的类,第一个是有20个double类型的大结构体,第二个是单个char类型。
这是编译器的任务这就是为什么在这种情况下类必须是完整类型的原因在类似的情况下,编译器需要这个:
struct foo {
short f;
int b;
};
…或类似的。当类型完成后,编译器可以决定类型的大小和字段的偏移量,以及在某些情况下需要知道的其他事情。
如果没有完整的类型定义,它将无法:
- 接受
foo
类型的变量声明(即foo f;
语句)。 - 接受
sizeof(foo)
表达 - 创建成员指针
- …等等。
因为你不能在没有完整类型的情况下声明变量f
,你就不能获得它的大小或访问它的成员。
如果在另一边使用了不完整类型。这是编译器只看到的:
struct foo;
编译器不能做任何需要完整类型的事情,但它可以有指向foo
的指针,但它不能查看它的内部,分配它或对它进行指针算术
您有一些误解,但是为了更好地理解,您可能会尝试在一些简单的结构体上使用<stddef.h>
中的offsetof( typename, membername )
宏。也许可以尝试打印offsetof( foo, a )
, offsetof( foo, b )
, (uintptr_t)&f
和(uintptr_t)&f.b
,看看编译器如何在给定f
的地址下找到f.b
。在类方法中,f
被命名为this
。
类的工作方式是这样的(另外,它们还有一个指向虚函数的指针表,当你调用一个虚函数时,你实际上是在调用该表中的第一个、第二个或第三个函数)。单继承的工作方式是,所有基类的成员和方法首先以相同的偏移量出现在派生类中。多重继承的工作方式很复杂。
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 我想知道我是否可以将一个类分配给特定的成员数据并创建该类的实例
- 调用C++成员函数指针,而不知道哪个类
- 这个成员函数没有被调用,我不知道如何纠正它
- llvm 如何知道成员函数指针是否指向虚函数?
- 将任意函数对象存储到类成员容器中,而无需知道其声明签名
- 指向成员的指针如何知道它绑定了哪个成员
- C 初始化数组成员,其长度在编译时由构造函数知道
- 成员函数模板推演指南或其他方法让编译器知道如何调用函数
- 指向成员函数的指针与指向数据成员的指针有何不同
- C 如何知道一类在C 中具有哪种类型的成员
- 我的类的成员函数无法正常工作。知道为什么吗?
- 如何在不知道C++中基类名称的情况下调用子类中基类的成员
- 如何在不提前知道成员名称的情况下编写函数来修改结构的成员值?
- 如何轻松知道编译器选择了哪些特殊成员函数
- C++:std::bind() 如何"知道"模板参数是指静态函数还是成员函数?
- 静态类成员得到"undefined reference"。不知道为什么
- C++错误:必须调用对非静态成员函数的引用,请帮忙,不知道字面上出了什么问题
- 如何知道特殊成员函数实现编译器自动生成
- c++在不知道对象类型的情况下定义成员函数指针