C++ 指向不完整类型的指针

C++ 指向不完整类型的指针,c++,oop,pointers,compiler-construction,incomplete-type,C++,Oop,Pointers,Compiler Construction,Incomplete Type,考虑以下几点: class Incomplete; class Complete { Incomplete* Foo; // Will only compile if Foo is a pointer. }; class Incomplete { Complete Bar; // Bar can be a pointer or an object. }; 指向不完整类型的指针如何合法?编译器如何知道不完整类型的对象有多大?既然它能明显地计算出大小,为什么不完整类型的常规对象

考虑以下几点:

class Incomplete;

class Complete
{
    Incomplete* Foo; // Will only compile if Foo is a pointer.
};

class Incomplete
{
    Complete Bar; // Bar can be a pointer or an object.
};

指向不完整类型的指针如何合法?编译器如何知道
不完整
类型的对象有多大?既然它能明显地计算出大小,为什么不完整类型的常规对象是非法的?

指针的大小并不取决于它所指向的类型的大小
int*
complete*
大小相同

但是,对于常规对象,大小未知

编译器如何知道不完整类型的对象有多大


没有。它与指针一起工作,因为编译器知道要为指针分配的大小

编译器不需要知道
complete
的实例有多大,因为指针的大小总是相同的。

指向不完整类型的指针是合法的,正是因为编译器不需要知道它们的大小

正如您所提到的,不能声明不完整类型的对象的原因是,编译器不知道对象有多大,因此无法为其分配空间。但是,当声明指向不完整类型的指针时,其大小是已知的,因为通常机器上的所有指针都具有相同的大小

此外,在声明指向不完整类型对象的指针时,不需要知道对象有多大。但是,如果您尝试使用不完整类型的对象,例如跟随该指针或尝试实例化该类型的对象,那么编译器将给您一个错误


简而言之,指针是合法的,因为它可以在编译器不知道指针大小的情况下创建。但是,如果您确实需要使用指针来了解该对象的大小或布局,编译器将需要更多关于该类型的信息。

此外,分配将在运行时完成,此时应该知道该对象的大小。由于指针的大小总是相同的,所以在执行应用程序时可以确定它所引用的对象的实际大小。如果大小未知,则分配代码不会编译,对于类成员对象(如上面示例中的complete::Bar)或新的动态分配也是如此,或堆栈上的分配。在编译器必须输入对象所需内存块大小的任何地方,如果类型不完整,编译器都会抱怨。