将类型用作字段时,为什么不能推迟不完整的类型预先声明大小计算?

问题描述

在以下代码中:

class B;

struct A
{
   B* b; // <- why MUST be a pointer? Why size cannot be calculated later...?
}

struct B
{
   ...
}

据我了解,结构A必须将b定义为B *,因为编译器在计算A的大小时无法告诉B的大小。

我不明白的原因是为什么编译器在找到B的完整定义之前不能推迟计算(正如程序员通过转发声明该类所承诺的那样)

解决方法

假设您可以A实际定义为:

class B;

struct A {
   B b; // not a pointer
}

也就是说,b不完整类型的数据成员 –编译器目前不知道B的大小。

然后,如果B被定义为:

struct B {
   A a;
}

这将需要无限的内存。

,

从本质上讲,指针是内存中的地址。要拥有这样的地址,您无需知道其指向的对象的大小。

但是使用不完整类型的指针并不能做很多事情。例如:

  • 您无法使用新表达式创建新对象(构造函数是什么?)

  • 您不能使用指针算术(对象的大小是多少?)

  • 等,请参阅here

具有指向不完整类型的指针的可能性实际上相当有用,例如,它允许PImpl idiom

,

原因很简单,C ++旨在通过一次遍历源代码(或多或少)进行编译;目的是使编译器不必推迟编译,因为在定义时没有足够的信息。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...