Qt报错: has initializer but incomplete type , 解决办法以及前向声明的错误使用

错误: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++编译器就能生成正确的符号表了。

相关文章
相关标签/搜索