错误:variable 'CPerson' has initializer but incomplete type
缘由:xxx对应的类型没有找到,只把xxx声明了可是没给出定义。编译器无从确认你调用的构造函数是什么,在哪儿
通常是没有包含定义xxx的头文件。c++
个人问题是写出了这样的代码函数
class CPerson; int main(int argc, char *argv[]) { CPerson tom; // error ... } class CPerson { // Define this class };
问题在于,对前向声明的错误使用this
前向声明的定义:有些时候咱们能够声明一些类可是并不去定义它,固然这个类的做用也颇有限了。指针
好比class foo;code
声明一个foo类,这个声明,有时候也叫作前向声明(forward declaration),在声明完这个foo类以后,定义完这个foo类以前的时期,foo类是一个不彻底的类型(incomplete type),也就是说foo类是一个类型,可是这个类型的一些性质(好比包含哪些成员,具备哪些操做)都不知道。对象
所以这个类的做用也颇有限.编译器
(1)不能定义foo类的对象。string
(2)能够用于定义指向这个类型的指针或引用。(颇有价值的东西)it
(3)用于声明(不是定义)使用该类型做为形参或者返回类型的函数。io
正由于有前向声明的存在,咱们在不少时候能够简便的作一些事情。
在c++中,若是要为类编写头文件的话,通常是要#include一堆头文件的,但利用前向声明和c++编译器的特性,其中大部分是不须要的。
c++编译器作的事情主要是:1.扫描符号;2.肯定对象大小。
因此不少时候并不须要将类都include进来。
好比:
(1)因为全部对象类型的引用所占用的空间都是相同大的,因此c++编译器很好确认对象大小。
class string;
class Sample
{
private:
string &s;
};
这里只须要作一个string的前向声明就能够了,不须要#include <string>
(2)因为全部类型的指针也是相同大小的。因此与(1)相似,也能够只作前向声明就好。
(3)声明成员函数的形参或者是返回类型,也能够利用前向声明的性质。
class string;
class foo;
class Sample
{
public:
foo foo_test(foo &);
private:
string &s;
foo *f;
};
这里,我根本没有定义一个foo类,可是仍是能够这样用,由于成员函数不占类对象的大小,因此c++编译器仍是能够肯定对象的大小。
前向声明的做用在于告诉编译器这个一个在别的地方定义的类型。这样C++编译器就能生成正确的符号表了。