最近在改一个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();
}

  

问题到此就解决完毕了~

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

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

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

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

    在构造自己的类时,可能会遇到两个类相互引用的问题. 例如: class A { int i; B b; }; class B { int i; A a; }; 在这种情况下,这样就会出现一个死循环a. ...

  3. Cocos Creator两个类相互引用(调用)

    如果两个类相互引用,脚本加载阶段就会出现循环引用,循环引用将导致脚本加载出错:///////////Game.jsvar Item = require("Item");var Ga ...

  4. 转载:C++中两个类中互相包含对方对象的指针问题

    原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某 ...

  5. 关于node中两个模块相互引用却不会死循环的问题

    关于node中两个模块相互引用却不会死循环的问题 node中是通过require来导入加载模块的,require有两个作用: 1.加载文件模块并执行里面的代码 2.拿到被加载文件模块导出的接口对象 现 ...

  6. C++中两个类相互包含引用问题

    在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { int i; B b; } class B { in ...

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

    在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 例如: Cup.h #ifndef CUP_H #define CUP_ ...

  8. css 规则中两个类连在一起是什么意思?

    原文地址:http://www.cxybl.com/html/wyzz/CSS/20120601/27374.html 比如: .c1.c2 { text-decoration:underline; ...

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

    在有时候由于类太大.须要在类在后面定义: 比如: class Y{ void f(X); }; class X{ //一些成员数据和函数 }; //error 由于c++要求不论什么一个变量在引用之前 ...

随机推荐

  1. solr与.net系列课程(八)solr中重跑索引的注意事项

    solr与.net系列课程(八)solr中重跑索引的注意事项 我们如果在项目中使用solr,那肯定就是把数据库中的数据跑进solr服务器中,solr有两种操作一种是新建索引,一种是增量索引,这里我们来 ...

  2. 能省则省:在ASP.NET Web API中通过HTTP Headers返回数据

    对于一些返回数据非常简单的 Web API,比如我们今天遇到的“返回指定用户的未读站内短消息数”,返回数据就是一个数字,如果通过 http response body 返回数据,显得有些奢侈.何不直接 ...

  3. Windows Phone编程中Dispatcher.BeginInvoke的使用

    在学习Windows Phone 程序开发时经常会使用到Dispatcher.BeginInvoke()的编程方法,可能许多初学者并不熟悉Dispatcher.BeginInvoke的使用方法以及为什 ...

  4. HTTP权威指南阅读笔记五:Web服务器

    Web服务器会做些什么: 1.建产连接:接受一个客户端连接,或者如果不希望与这个客户端建立连接,就将其关闭. 1)处理新连接 2)客户端主机名识别 3)通过ident确定客户端用户 ident在组织内 ...

  5. Redis教程(八):事务详解

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/135.html?1455806987 一.概述: 和众多其它数据库一样,R ...

  6. Java程序员的日常——经验贴(纯干货)二

    继昨天的经验贴,今天的工作又收获不少. windows下编辑器会给文件添加BOM 在windows的编辑器中,为了区分编码,通常会添加一个BOM标记.比如,记事本.nodepade++.sublime ...

  7. 使用paramikoHelper类实现MySQL安装和数据恢复

    本脚本实现远程Linux主机登陆和安装MySQL的rpm包,同时导入mysql数据,实现自动化安装 paramikoHelper类在本博客中 http://www.cnblogs.com/djoker ...

  8. Leetcode 66 Plus One STL

    题意让大数加1 我的做法是先让个位+1,再倒置digits,然后进位,最后倒置digits,得到答案. class Solution { public: vector<int> plusO ...

  9. “LAMP“或“LNMP”组合

    Linux作为操作系统,Apache和 Nginx作为 Web 服务器,MySQL 作为数据库,PHP/Perl/Python作为服务器端脚本解释器. 由于这四个软件都是免费或开放源码软件(FLOSS ...

  10. solr课程学习系列-solr服务器配置(2)

    本文是solr课程学习系列的第2个课程,对solr基础知识不是很了解的请查看solr课程学习系列-solr的概念与结构(1) 本文以windows的solr6服务器搭建为例. 一.solr的工作环境: ...