类相互引用问题

在C语言中,如果头文件不加任何保护的话,两个头文件相互包含会导致编译出错,如下面两个文件:

a.h

#include "b.h"

b.h

#include "a.h"

使用gcc编译的话,会报下面的错误:

from main.c:2:
b.h:1:15: error: #include nested too deeply
#include "a.h"
^
make: *** [all] Error 1

这是一个无限循环,如果加了保护性的代码,则不会出现这种情况:

// file "b.h"
#ifndef _B_H
#define _B_H

#include "a.h"

#endif

// file "a.h"
#ifndef __A_h
#define __A_h

#include "b.h"

#endif

在C++中,情况也是如此,当然此文的重点并不是头文件的保护这个问题,而是两个类相互引用的问题。如果在类中中有一个类B的引用实例,同时类B中也有A的一个引用实例,或者是有接口的形参是对方的引用或指针,则会遇到类似的问题:

// file "a.h"

#ifndef _A_H
#define _A_H

#include "a.h"

class B
{
    B(){};

private:
    A *a;
};

#endif

// file "b.h"

#ifndef _A_H
#define _A_H

#include "a.h"

class B
{
    B(){};

private:
    A *a;
};

#endif

编译时会报下面的错误:

g++ main.cpp
In file included from a.h:4:0,
from main.cpp:1:
b.h:12:5: error: ‘A’ does not name a type
A *a;
^
make: *** [all] Error 1

我们从a.h的角度来考虑,编译器遇到#include "b.h"语句时,则会把这个文件在原地展开,b.h中的include "a.h"当然不会再起任何作用(虽然a.h的文件内容还是会被复制过来,但是已经不会被编译处理了),但是b.h文件中的其它部分还是会被编译器处理,当遇到class B定义中的A *a;时,因为class A还没有被定义,所以就会报不认识A的错误。

这个时候只要在b.h中class B定义之前,声明一下A是一个类即可。使用这种方法在class A声明之前,只可以定义class A的引用或指针,不可以定义A的实例。

#ifndef _A_H
#define _A_H

#include "a.h"

class A;

class B
{
    B(){};

private:
    A *a;
};

#endif

理论上只要在一个b.h中做这样的声明就可以了,a.h中是不需要类似的声明的,但是建议出现这种交叉引用的情况都用一下前向声明比较好。

时间: 2024-10-09 20:20:45

类相互引用问题的相关文章

c++中两个类相互包含引用的相关问题

在构造自己的类时,可能会遇到两个类相互引用的问题. 例如: class A { int i; B b; }; class B { int i; A a; }; 在这种情况下,这样就会出现一个死循环a.b.a.b.a.b....,一般来说,应避免这种情况. 如果确实需要的话,一般来说,至少有一方需要定义成指针. 例如: class A { int i; B b; }; class B { int i; A* a; }; 如果按照以上的方式,既然存在互相引用,就必须互相包含头文件,如果仅仅是在自己的

【转】 C++中两个类相互包含引用问题

原文:http://blog.csdn.net/leo115/article/details/7395077 在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { int i; B b; } class B { int i; A* a; } 请注意上面的定义内容,一般情况下是不能出现类A,类B相互引用都定义对象,即如下的样子: class A { int i; B b; } class B { int

C++两个类相互包含引用的问题

在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { B b; } class B { A* a; } 请注意上面的定义内容,一般情况下是不能出现类A,类B相互引用都定义对象,即如下的样子: class A { B b; } class B { A a; } 编译器在声明A的时候,由于B的声明在A的下面所以出现编译错误 那么,在定义时因为相互引用肯定会需要相互包含头文件,如果仅仅只是在各自的头文件中包含

利用delegate来解决类之间相互引用问题(引用死锁)

类之间相互引用--类A中需要调用类B中的方法,同时,类B中又要调用类A中的方法.(也被称为引用死锁,通常会出现编译错误). 解决方法是,在类A中引用类B,并使类A成为类B的delegate,这样在类A中就可以调用类B中的方法,而在类B中可以设一个delegate属性,(这个delegate其实就是类A)就可以用[delegate msg]的方式来调用类A中的方法了. 具体实现如下: ** classA.h : @interface ClassA<ClassBDelegate> { ClassB

多态时最好将基类的析构函数设为virtual、 C++中两个类相互包含引用问题 (转载)

多态:http://blog.csdn.net/tmljs1988/article/details/8146521 C++中两个类相互包含引用问题:http://blog.csdn.net/leo115/article/details/7395077 http://blog.csdn.net/tmljs1988/article/details/6081132

两个类相互包含引用的问题--类前向声明

1.背景 编程中遇到如下错误:使用不完全类型**以及**前向声明. 查找相关资料后发现是类的前向声明(forward declaration)问题:在程序中声明一个类后,此类是一个不完全类型(incompete type),即已知此类是一个类型,但不知道包含哪些成员. 不完全类型只能以有限方式使用,不能定义该类型的对象.不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数. 2.为什么需要前向声明 在构造自己的类时,有可能会碰到两个类之间

Struts2标签与Jsp的嵌入Java代码之间的变量相互引用

新年的第一天,对programer来说,和往常相比并没有太大不同,代码照样敲.做了一天键盘侠,不见得有什么出彩的成就(其实一直以来似乎都是这样/(ㄒoㄒ)/~~),倒是被曾经绊住的问题再次绊住然后纠结地解决了,顺便复习了一下.问题就是在Struts2标签和Jsp的Java代码直接实现了变量相互引用. 情景1:有一个在valuestack里面有一个变量,而我们目标除了获得这个值之外,还可能会更改它的值,这个操作可能是通过webservice,service.dao等进行,而这些操作都要进行Java

c++中两个类互相引用的问题

最近在改一个C++程序的时候碰到一条警告信息,警告信息为:“ 删除指向不完整“Q2DTorusNode”类型的指针:没有调用析构函数                1> c:\users\lxw\desktop\dragonfly第二阶段实验\最终的实验版本\实验目录\dragonfly_modify\src\Q2DTorus.h(6) : 参见“Q2DTorusNode”的声明 ” 警告信息很是奇怪,其实出于强迫症的原因想要解决掉这个警告信息,而且从警告信息来看,程序也应该存在内存泄露的问题,

C++中两个类相互include的问题

在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 例如: Cup.h #ifndef CUP_H #define CUP_H #include "Box.h" class Cup { public: ~Cup(); Box b; Cup(); }; #endif // CUP_H Cup.cpp #include "Cup.h" #include <iostream> usin