[cpp primer随笔] 16. 【不完整类型】的概念

我相信很多人都曾在学习C++的过程中,像下面这样干过:

class Example{
	Example obj; // error: 不允许使用不完整的类型
};

即在类A中,定义A类型的成员变量。此时编译是无法通过的,我们会得到不允许使用不完整的类型这样冷冰冰的报错。

这就引出了这篇文章要分享的话题:什么是【不完整类型】?


与函数相同,类类型的定义可以拆分为声明与定义两部分。

class Example; // 声明

class Example{ // 声明 + 定义
	// ...
};

声明的作用是在当前的作用域环境下,使类名可见。定义的作用则是指定该类型所拥有的具体成员。只要一个类型完成了声明,那么编译器就会意识到有这样一个类型存在。但只要该类类型的定义没有完成,这就是一个不完整类型。

不完整类型是指只进行了声明,却没有完成定义的类类型。

在最开始的例子中,由于Example的定义尚未完全结束,此时Example属于不完整类型,这便是报错的原因。

那么为什么C++禁止使用不完整类型呢?

因为,将类型本身用于定义成员变量,是一件很逆天的事情。因为你无法确定在这种层层嵌套下,一个该类型对象的大小究竟是多少!这样程序将无法有效分配内存空间。为此,必须杜绝使用不完整类型来定义变量。

但若将上面的例子改一下,我们将Example类型的成员换成其指针类型Example*,编译是可以通过的。

class Example{
private:
	Example * p_obj; // 编译通过
};

因为指针类型是完整的,无论指向的何种类型,只需确保该种类型的名字在当前作用域下可见即可。 另外,从确定成员所占大小的角度考虑,在C++中,指针的大小是固定的,与指向的具体类型无关。

你可能感兴趣的:(C++,c++)