关于超前引用

超前引用在我们的程序中经常用到,解决的方法有两种:一种是在使用超前用的类的声明前对超前引用的类进行声明(自认为这表述不是很好,如果不明白的话看后面的例子就可以了);一种是在使用超前用的类的声明前加头文件。在我的印象里这两种方法的效果是一样的。抱着这种想法,根据<<Effective C++>>那本书的建议,我把一个程序的.h文件中的头文件声明形式改成类的声明,没想到到编译出错了。经过在网上查了一些资料,终于搞清楚了二者之间用法的区别。为了进一步进行验证和加深理解,做了一下测试:

1

//

//------------------------class A--------------------------------

A.h文件

 

#pragma once

 

class A

{

public:

       A(void);

       ~A(void);

};

 

A.cpp文件

 

#include "StdAfx.h"

#include "./a.h"

 

A::A(void)

{

}

A::~A(void)

{

}

 

///

//----------------------class B-----------------------------------

B.h文件

 

#pragma once

 

class A;

class B

{

public:

       A *a;

       B(void);

       ~B(void);

};

 

B.cpp文件

 

#include "StdAfx.h"

#include "./b.h"

 

B::B(void)

{

}

B::~B(void)

{

}

 

其他无关的代码略去,在VS.NET2003下进行编译,编译结果为:

 

---------------------- 完成 ---------------------

 

    全部重新生成: 1 已成功, 0 已失败, 0 已跳过

 

2

 

但是当我把B.h文件的A *a;改成A a;之后,:

 

#pragma once

 

class A;

class B

{

public:

       A a;

       B(void);

       ~B(void);

};

 

重新编译,结果却是:

f:/VC_Case/refrence7/refrence7/B.h(6) : error C2079: B::a”使用未定义的 classA

A.cpp

refrence7.cpp

正在生成代码...

生成日志保存在“file://f:/VC_Case/refrence7/refrence7/Debug/BuildLog.htm”中

refrence7 - 1 错误,0 警告

 

---------------------- 完成 ---------------------

 

    全部重新生成: 0 已成功, 1 已失败, 0 已跳过

 

3

 

如果再把B.h文件改成如下形式:

#pragma once

 

#include "A.h"

 

class B

{

public:

       A a;

       B(void);

       ~B(void);

};

 

得到的编译结果:

--------------------- 完成 ---------------------

    全部重新生成: 1 已成功, 0 已失败, 0 已跳过

 

哈哈,竟然成功了.

 

于是得出结论:(以上面的例子来说明)

 

(1)  如果用class A来定义一个引用和指针作为class B的一个成员,class B的声明之前加“ class A;  和“ #include "A.h "效果是相同的,但为了防止“ A,h ”重复编译,建议使用class A;

 

(2)  如果用class A来定义一个变量作为class B的一个成员,则只能在class B的声明之前加“ #include  A.h" ”。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页