c/c++中的incomplete type(不完全类型)
[TOC]
##问题的引入
《The C Programming Language》里讲到:
If a specifier with a tag but with out a list appears when the tag is not declared,an incomplete tpye is specified.
它包括:
void、 未指定长度的数组 以及具有非指定内容的结构和联合
##它的应用场景
为了将私有模块的内部实现细节对提供公共接口的模块隐藏,在公共接口模块中使用不完全类型:共有头文件中只定义结构体的标识符,实现的定义是有私有头文件传给公有头文件的。
比如:
##不完全类型什么时候会变成 “完全的”
- 当后续的一个包含声明列表的一个同样的标识符出现时
- 即使包含了声明列表的标识符的列表中,该标识符也是不完全的,只有当}出现时,该标识符才完全
##不完全类型的特性
- 由于struct 或者 union 不能包含 incomplete type的成员,所以因为上面的第二条原因,结构和联合不能包含自己的实例(因为在自己的声明列表还没有遇到}之前,自己的标识符还是一个incomplete type)。
- 但是,structure or union type可以包含自引用类型的结构,比如指向自身实例的指针,因为指向不完全类型的指针可以被声明。
- 对不完全类型也不能使用sizeof,因此,在compile time,我们是无法知道一个不完全类型的大小的。
##精髓来了!!!
为什么c/c++中如果定义了两个头文件,其中的类或者结构互相引用(写程序经常会遇到这种情况),这种情况下,要想通过编译,不能在两个头文件中都#include对方,只能在其中一个里面#include,而在另一个被#include的头文件中 对用到的另一个文件中定义的类或者结构进行声明(其实这个声明就是一个不完全类型啊)
关于这个特性,《The C Programming Language》p213中有一段话特别精髓:
A very special rule applies to declarations of the form struct-or-union identifier; that declare a structure of union,but have no declaration list and no declarators. Even if the identifier is a structure or union tag already declared in an outer scope, this declaration makes the identifier the tag of a new,incompletely-typed structure or union in the current scope.
this recondite rule is new with ANSI. It is intended to deal with mutually-recursive structures declared in an inner scope,but whose tags might already be declared in the outer scope.
|
|
|
|