在分析Qt程序的时候有一个地方是让我想了很久问题,几乎花了半个星期的时间来弄清楚这个问题,现在终于有点眉目,记录下这些东西。
- 原来的程序是这样的:
#ifndef MYDLG_H#define MYDLG_H#include //#include namespace Ui {class myDlg;//命名空间的声明是怎么样的?这个应该是前导声明}class myDlg : public QDialog//继承自QDialog{ Q_OBJECTpublic: explicit myDlg(QWidget *parent = 0); ~myDlg();private: Ui::myDlg *ui;//在是在namespace Ui里面的myDigprivate slots: void on_enterBtn_clicked();};//这个应该是类得接口部分#endif // MYDLG_H
不知道这个是那里冒出来的?关键是不知道里面的东西是什么。后来在网上和书上查了很久知道这个是前导声明,那么什么是前导声明呢?下面我们来解释什么是前导声明引用一篇文章本文通过实例分析有关编译时头文件包含的相关问题,首先从简单的例子入手,然后步步改进,最后得出解决方案。#include#ifndef#endif是基本的语法问题在这里就不冗述了。首先看一个简单的include例子:
A.h
#ifndef _A_
#define _A_
#include "B.h"
class A
{
public:
int id;
B b;
};
#endif
B.h
#ifndef _B_
#define _B_
#include "A.h"
class B
{
public:
int id;
A a;
};
#endif
main.cpp
#include "A.h"
#include "B.h"
int main()
{
A a;
B b;
}
编译main.cpp时,遇到第一条include,进入A.h,首先定义宏_A_,然后包含B.h,定义宏_B_,下一句包A.h,由于宏_A_已经定义,因而A.h不再包含,接着声明类型B,但是类型A尚未声明,因此编译器抛出了erro:error C4430: missing type specifier。类A和类B需要彼此互相包含,这样必然会有一个类会先被定义,而另外一个类后被定义,这样在先被定义的类引用后被定义的类的时候,就导致了所谓的超前引用。相互包含编译不通过,可以改为前导申明解决,按下面3条来改:
- 将A.h中的#include “B.h”去掉
- 在类A前声明class B;
- 将B b;改成B* b;因为B的类型虽然声明了,但是需要多大的空间是未知的,然而指针的空间大小事可以确定的。
然而这样改能完全解决问题吗?当我们需要在A类中使用B类的指针去访问B的成员int id时,这时候又会抛出编译错误:error C2027: use of undefined type。原因是前导声明不能告诉编译器B的具体内容。解决方法:在b.cpp中加入include ”B.h”。当然也可以直接都使用前导声明,不包含对方头文件:
- 分别定义Class A和Class B
- 在两个头文件的开头分别用class ClassB;和class ClassA;声明对方
- 在两个cpp文件中分别包含另外一个类的头文件
上面的这篇文章就写了什么是前导声明,其实就是还没有定义这个东西要先拿来使用了,所以要声明这个是什么意思,当然使用也是有限制的,那就是它还不知道里面有什么东西,因此只能够使用指针。在使用这个的东西的时候也要注意就是要include被前导声明的类。因为前导声明只是提醒什么类型,但是里面的具体什么东西还是不知道的。
阅读(946) | 评论(0) | 转发(0) |