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();
}
问题到此就解决完毕了~
c++中两个类互相引用的问题的更多相关文章
- 多态时最好将基类的析构函数设为virtual、 C++中两个类相互包含引用问题 (转载)
多态:http://blog.csdn.net/tmljs1988/article/details/8146521 C++中两个类相互包含引用问题:http://blog.csdn.net/leo11 ...
- c++中两个类相互包含引用的相关问题
在构造自己的类时,可能会遇到两个类相互引用的问题. 例如: class A { int i; B b; }; class B { int i; A a; }; 在这种情况下,这样就会出现一个死循环a. ...
- Cocos Creator两个类相互引用(调用)
如果两个类相互引用,脚本加载阶段就会出现循环引用,循环引用将导致脚本加载出错:///////////Game.jsvar Item = require("Item");var Ga ...
- 转载:C++中两个类中互相包含对方对象的指针问题
原文链接:http://www.cnblogs.com/hanxi/archive/2012/07/25/2608068.html 前几天很不爽,因为C++中两个类中互相包含对方对象的指针编译时提示某 ...
- 关于node中两个模块相互引用却不会死循环的问题
关于node中两个模块相互引用却不会死循环的问题 node中是通过require来导入加载模块的,require有两个作用: 1.加载文件模块并执行里面的代码 2.拿到被加载文件模块导出的接口对象 现 ...
- C++中两个类相互包含引用问题
在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { int i; B b; } class B { in ...
- C++中两个类相互include的问题
在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 例如: Cup.h #ifndef CUP_H #define CUP_ ...
- css 规则中两个类连在一起是什么意思?
原文地址:http://www.cxybl.com/html/wyzz/CSS/20120601/27374.html 比如: .c1.c2 { text-decoration:underline; ...
- C++中没有定义类的引用。
在有时候由于类太大.须要在类在后面定义: 比如: class Y{ void f(X); }; class X{ //一些成员数据和函数 }; //error 由于c++要求不论什么一个变量在引用之前 ...
随机推荐
- Dynamic CRM 2015学习笔记 系列汇总
这里列出所有 Dynamic CRM 2015学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址:Dynamic CRM 2015学习笔记 系列汇总 一 ...
- [备忘][转]rsync使用时的常见问题
sync使用时的常见问题: 错误1: rsync: read error: Connection reset by peer (104) rsync error: error in rsync pro ...
- JDK环境变量的配置方法
1.打开我的电脑--属性--高级--环境变量 2.新建系统变量JAVA_HOME 变量名:JAVA_HOME 变量值:jdk的目录,比如d:/java 3. 选择“系统变量”中变量名为“Path”的环 ...
- 解决pageControl页面设置无效问题
废话不多说,先上代码 1.添加pageViewControl - (void)addPageControl { UIPageControl *pageControl = [[UIPageControl ...
- js系列(8)简介
JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HT ...
- discuz x3在DIY模块中调用伪静态不成功,显示动态链接的解决办法
discuz x3在DIY模块中调用伪静态不成功,显示动态链接,然而其他的链接正常显示伪静态. 后台启用伪静态后,发现论坛版块.帖子点击链接,伪静态正常显示,然后在门户首页DIY显示的帖子,点进去后发 ...
- Linux/Unix 怎样找出并删除某一时间点的文件(转)
在Linux/Unix系统中,我们的应用每天会产生日志文件,每天也会备份应用程序和数据库,日志文件和备份文件长时间积累会占用大量的存储空间,而有些日志和备份文件是不需要长时间保留的,一般保留7天内的文 ...
- windows 隐藏文件方法
隐藏: 然后在里面输入:attrib +s +a +h +r f:\123 (f的意思就是F盘,123就是你新建的文件夹名字),然后按回车,你会发现F盘下的123文件夹不见的,其实就是被你隐藏了. 文 ...
- 15个最好的PDF转word的在线转换器,将PDF文件转换成doc文件
PDF是一种文件格式,包含文本,图像,数据等,这是独立于操作系统的文件类型.它是一个开放的标准,压缩,另一方面DOC文件和矢量图形是由微软文字处理文件.该文件格式将纯文本格式转换为格式化文档.它支持几 ...
- rocketmq总结
1:角色关系 2:顺序消息 消费消息的顺序要同収送消息的顺序一致,在 RocketMQ 中,主要挃的是尿部顺序,即一类消息为满足顺序性,必须 Producer 单线程顺序収送,丏収送到同一个队列,返样 ...