C++类相互包含问题

CA类包含CB类的实例,而CB类也包含CA类的实例。代码如下

//A.h实现CA类的定义                        //B.h实现CB类的定义        

#include "B.h"                           #include "A.h"               int main()

class CA                              class CB                  {

{                                  {                        CA instanceA;

  public:                               public:                    return 0;

    int iData;                            int iData;                }

    CB instaceB;                           CA instaceA;

};                                 };

编译出错分析:

CA类定义时使用CB类的定义,CB类定义时使用CA类的定义,递归定义

A.h包含了B.h,B.h包含了A.h,也存在递归包含的问题

其实,无论是结构体的递归定义,还是类的递归定义,最后都归于一个问题,C/C++采用静态编译模型,在程序运行时,结构或类大小都会在编译后确定。程序要正确编译,编译器必须知道一个结构或结构所占用的空间大小,否则编译器就会报出奇怪的编译错误。

解法:

1.向前声明实现

//A.h实现CA类的定义                        //B.h实现CB类的定义

class CB//前向声明CB类                      #include "A.h"                #include "B.h"

class CA                              class CB                    int main()

{                                  {                        {

  public:                               public:                      CA instaceA;

    int iData;                            int iData;                    return 0;

    CB* pinstaceB;                         CA instaceA;                }

};                                 };

前向声明实现方式的主要实现原则

主函数只需要包含B.h就可以,因为B.h中包含了A.h

A.h中不需要包含B.h,但要声明class CB,在避免死循环的同时也成功引用了CB

包含class CB声明,而没有包含头文件B.h,这样只能声明CB类型的指针,而不能实例化

2.friend声明定义

//A.h实现CA类的定义                        //B.h实现CB类的定义

class CB//前向声明CB类                      #include "A.h"                #include "B.h"

class CA                              class CB                    int main()

{                                  {                        {

  public:                               public:                      CA instaceA;

    friend classCB;  //友元类声明

    int iData;                            int iData;                    return 0;

    CB* pinstaceB;                         CA instaceA;                }

};                                 };

friend友元声明实现说明:

主函数只需要包含B.h就可以,因为B.h中包含了A.h

A.h不需要包含B.h,但要声明class CB,在避免死循环的同时也成功引用了CB

class CA包含class CB友元声明,而没有包含头文件B.h,这样只能声明CB类型的指针,而不能实例化

无论是前向声明还是friend友元实现,有一点是肯定的,即最多只能有一个类可以定义实例。同样头文件包含也是一件很麻烦的事情,再加上头文件中常常出现的宏定义,各种宏定义的展开是非常耗时间的

类或结构体递归定义实现应遵循两个原则

1.如果可以不包含头文件,那就不要包含了。这时候前置声明可以解决问题的。如果使用的仅仅是一个类的指针,没有使用这个类的具体对象,也没有访问到类的具体成员,那么前置声明就可以了。因为指针这一数据类型的大小是特定的,编译器可以获知。

2.尽量在cpp文件中包含头文件,而非在头文件。假设类A的一个成员是一个指向类B的指针,在类A的头文件中使用了类B的前置声明并编译成功,那么在A的实现中需要访问B的具体成员,因此需要包含头文件,那么我们应该在类A的实现部分包含类B的头文件而非声明部分。

时间: 2024-08-08 13:51:08

C++类相互包含问题的相关文章

多态时最好将基类的析构函数设为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

【转】 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++中两个类相互包含引用的相关问题

在构造自己的类时,可能会遇到两个类相互引用的问题. 例如: 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++两个类相互包含引用的问题

在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类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的下面所以出现编译错误 那么,在定义时因为相互引用肯定会需要相互包含头文件,如果仅仅只是在各自的头文件中包含

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

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

解决两类相互包含使用另一个类成员函数

// VistorMode.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <IOSTREAM> using namespace std; class B; class A{ public: /* void getBaction(B * p){ p->action(); //会出错,error:use of undefined type

qt c++对象头文件如何相互包含

今天在写qt时,遇到了两个类相互包含的问题,类A要用到类B,类B要用到类A. 类A:a.h #ifndef A_H #define A_H #include <b.h> class A { public: A(); }; #endif // A_H a.cpp #include "a.h" A::A() { B b; } 类B:b.h #ifndef B_H #define B_H #include <a.h> class B { public: B(); };

C/C++ 中头文件相互包含引发的问题

今天下午遇到一个头文件相互包含而导致的编译问题,花了我不少时间去调试没找到问题,最后晚上跟师兄讨论不少时间,突然有所顿悟! 问题重现 我把问题脱离于项目简单描述一下:我写了一个函数 bool func(ClassA* CA) 需要加到项目中,我就把这个函数的声明放到 head1.h 中,函数参数类型 ClassA 定义在另一个头文件 head2.h 中,因此我需要在 head1.h 中包含 head2.h:而 head2.h 中之前又包含了 head1.h,这样就构成了一种头文件相互包含的场景.

C程序中头文件相互包含精华(转载)

C程序中头文件相互包含精华(网摘小结) 收藏(转自:http://blog.csdn.net/lingyun3429/archive/2010/04/27/5535191.aspx).h中一般放的是同名.c文件中定义的变量.数组.函数的声明,需要让.c外部使用的声明. 1)h文件作用 1 方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明: 2 提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h). 2)h文件里应该有什么 常量,结构,类型定义,函数,