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

  最近在改一个C++程序的时候碰到一条警告信息,警告信息为:“

删除指向不完整“Q2DTorusNode”类型的指针;没有调用析构函数
                1> c:\users\lxw\desktop\dragonfly第二阶段实验\最终的实验版本\实验目录\dragonfly_modify\src\Q2DTorus.h(6) : 参见“Q2DTorusNode”的声明

警告信息很是奇怪,其实出于强迫症的原因想要解决掉这个警告信息,而且从警告信息来看,程序也应该存在内存泄露的问题,因为警告直接明白告诉你了,没有调用析构函数,接下来就是我解决的过程。我会搭建一个简单的程序来模拟这个错误,因为程序是在有些多~

警告的来源:

一个头文件A.h包含class A的代码如下:

#ifndef AH
#define AH
class B;
class A {
	B *memb;
	A() {

	}
	~A() {
		delete memb;
	}
};
#endif

  一个头文件B.h包含class B的代码如下:

#ifndef BH
#define BH
class B {

};
#endif

     此时编译就会产生类似上面的警告信息:warning C4150: 删除指向不完整“B”类型的指针;没有调用析构函数。

原因分析:

   因为class A中B的声明依赖于class B的前置声明,而不是#include "B.H",所以B的定义对A来说不可见,所以无法调用析构函数,导致内存泄露。

程序的变化

此时如果class A和class B相互保持对方类型的成员会如何呢?

A.h的代码:

#ifndef AH
#define AH
class B;
class A {
	B b;
};
#endif

   B.h的代码:

#ifndef BH
#define BH
#include "A.h"
class B {
    A a;
};
#endif

  这段代码存在问题,因为如果静态定义对象A,B,此时必定存在一个对象的定义对于另外一个对象的定义不可见,所以定义失败。如果均是利用#include对方,取决于编译器的顺序必定一个定义不可见。然而前置声明不能定义对象。

解决方案:

      此种状况的解决利用前置声明定义的那个类中的保持另外一个类的引用定义为指针,定义指针时不需要对那个类的定义可见。

另外的问题:

    A.h

#ifndef AH
#define AH
class B;
class A {
	B* b;
	void setB() {
		b->haha();
	}
	~A() {
		delete b;
	}
};
#endif 

    B.h

#ifndef BH
#define BH
#include "A.h"
class B {
    A a;
	void haha() {

	}
};
#endif

但是利用前置声明导致定义指针成员的类会出现最开始说的warning警告,因为定义不可见的原因。

“warning C4150: 删除指向不完整“B”类型的指针;没有调用析构函数”

而且另外的一个问题是在该.h文件中不能使用该指针调用这个类的成员,原因也是定义不可见。

“error C2227: “->haha”的左边必须指向类/结构/联合/泛型类型”

解决方案:

此时需要将A.h的所有成员函数实现重新定义一个.cpp文件,然后该.cpp文件去#include 指针成员类的头文件声明,此时定义可见,即可定义析构函数,调用指针的类成员了。

A.h

#ifndef AH
#define AH
class B;
class A {
public:
	B* b;
	void setB();
	~A();
};
#endif

  

B.h

#ifndef BH
#define BH
#include "A.h"
class B {
public:
    A a;
	void haha() {

	}
};
#endif

  

A.cpp

#include "A.h"
#include "B.h"
A::~A() {
	delete b;
}
void A::setB() {
	b->haha();
}

  

问题到此就解决完毕了~

时间: 2025-01-16 17:35:53

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

C++中两个类互相引用的解决方法

一.问题描述 现在有两个类A和B需要定义,定义A的时候需要用到B,定义B的时候需要用到A. 二.分析 A和B的定义和调用都放在一个文件中肯定是不可以的,这样就会造成两个循环调用的死循环. 根本原因是:定义A的时候,A的里面有B,所以就需要去查看B的占空间大小,但是查看的时候又发现需要知道A的占空间大小,造成死循环. 解决方法1: (1)写两个头文件A.h和B.h分别用于声明类A和B: (2)写两个.cpp文件分别用于定义类A和B: (3)在A和B的头文件中分别导入对方的头文件. 解决方法2: (

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; }; 如果按照以上的方式,既然存在互相引用,就必须互相包含头文件,如果仅仅是在自己的

多态时最好将基类的析构函数设为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://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某一个类未定义...所以我就想啊想,这样也对,我的头文件都有#ifndef的,包含了一次就不能再包含了,以为就实现不了这样的功能,于是就改了设计方案: class A { public: A(B* pB):m_pB(pB) { } private: B* m_pB; }; class B { publ

C++中未定义类的引用。

在有时候因为类太大,需要在类在后面定义: 例如: class Y{ void f(X); }; class X{ //一些成员数据和函数 }; //error 因为c++要求任何一个变量在引用之前必须声明.,在上述定义中我们可以调换两者的顺序来实现. 但是如果形成了循环? class X{ void f1(Y) }; class Y{ void f(X); }; //error 这种就不能通过简单的调换顺序来通过编译器在调用之前必须声明的金科玉律了. 那么我们可以通过在上述中先声明? class

【转】 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++中两个类相互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

C++中没有定义类的引用。

在有时候由于类太大.须要在类在后面定义: 比如: class Y{ void f(X); }; class X{ //一些成员数据和函数 }; //error 由于c++要求不论什么一个变量在引用之前必须声明. .在上述定义中我们能够调换两者的顺序来实现. 可是假设形成了循环? class X{ void f1(Y) }; class Y{ void f(X); }; //error 这样的就不能通过简单的调换顺序来通过编译器在调用之前必须声明的金科玉律了. 那么我们能够通过在上述中先声明? c

类相互引用问题

在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 这是一个无限循环,如果加了保护性的代码,则不会出