今天在写qt时,遇到了两个类相互包含的问题,类A要用到类B,类B要用到类A。

类A:a.h

  1. #ifndef A_H
  2. #define A_H
  3.  
  4. #include <b.h>
  5.  
  6. class A
  7. {
  8. public:
  9. A();
  10. };
  11. #endif // A_H

a.cpp

  1. #include "a.h"
  2.  
  3. A::A()
  4. {
  5. B b;
  6. }

类B:b.h

  1. #ifndef B_H
  2. #define B_H
  3.  
  4. #include <a.h>
  5.  
  6. class B
  7. {
  8. public:
  9. B();
  10. };
  11. #endif // B_H

b.cpp

  1. #include "b.h"
  2.  
  3. B::B()
  4. {
  5. A a;
  6. }

按上面这种写法编译是有问题的。

对于a.cpp,包含了a.h,所以先将a.cpp展开,如下

  1. #ifndef A_H
  2. #define A_H
  3.  
  4. #include <b.h>
  5.  
  6. class A
  7. {
  8. public:
  9. A();
  10. };
  11.  
  12. #endif // A_H
  13.  
  14. A::A()
  15. {
  16. B b;
  17. }

这样其实还看不出来,所以继续对#include <b.h>展开,展开时还需加上b.cpp里的代码,如下

  1. #ifndef A_H
  2. #define A_H
  3.  
  4. #ifndef B_H
  5. #define B_H
  6.  
  7. #include <a.h> //对于这一句,由于第二行定义过A_H,将不会在对其展开,所以这一句可以去掉。
  8.  
  9. class B
  10. {
  11. public:
  12. B();
  13. };
  14.  
  15. #endif // B_H
  16.  
  17. B::B()
  18. {
  19. A a;
  20. }
  21.  
  22. class A
  23. {
  24. public:
  25. A();
  26. };
  27.  
  28. #endif // A_H
  29.  
  30. A::A()
  31. {
  32. B b;
  33. }

看上面代码会发现B类的构造函数里使用的A在A类的声明之前,所以问题就出现了,A类未定义。

所以解决的办法就是添加前置声明,在包含头文件的直接前面或者直接后面加上这个类的声明,对于上面这个例子,解决方式就是在类的头文件中加上包含类的前置声明,如下:

a.h

  1. #ifndef A_H
  2. #define A_H
  3.  
  4. class B;
  5. #include <b.h>
  6. //class B;
  7.  
  8. class A
  9. {
  10. public:
  11. A();
  12. };
  13.  
  14. #endif // A_H

b.h

  1. #ifndef B_H
  2. #define B_H
  3.  
  4. class A;
  5. #include <a.h>
  6. //class A;
  7.  
  8. class B
  9. {
  10. public:
  11. B();
  12. };
  13.  
  14. #endif // B_H

qt c++对象头文件如何相互包含的更多相关文章

  1. QT 头文件之间相互包含会报错:类名不存在

    "希望是一个美好的东西! 希望, 这能自己给自己,否则只有无尽的痛苦和迷茫!"---Frank 假设你写了两个类A和B,如果在A.h中有 #include<B.h>;  ...

  2. 下位机多个".c, .h"文件的相互包含及排版

    一.背景: 自从接触单片机编程以来,由于工作上的需要,不可避免的时常会接手别人的代码,但常常由于上一位同事的编码随意性有点大,导致可读性非常的差,有时候不得不完全舍弃原有代码,推倒重来,无形中增加了工 ...

  3. 【C】.h头文件的重复包含问题

    .h头文件存在的意义就是封装,可以方便多个.c源文件使用,但要防止.h头文件被同一个.c源文件多次包含. 例如, io.h文件 #ifndef _IO_H_ #define _IO_H_ #defin ...

  4. <bits/stdc++.h>头文件介绍(包含源代码)

    注:转自http://blog.csdn.net/charles_dong2/article/details/56909347,同为本人写的,有部分修改. 之前在一个小OJ上刷题时发现有人是这么写的: ...

  5. cocos2d-x 扩充引擎基类功能 引起的头文件重复包含问题的分析

    c++ 头文件包含 原因的分析:   c++  头文件的循环引用是指: .h 里面的里面的头文件的相互包含的,引起的重复引用的问题.cpp 里面包含头文件是不存在重复引用的问题(因为CPP没有#ifn ...

  6. Qt Creator中,include路径包含过程(或如何找到对应的头文件)

    Qt Creator中,include路径包含过程(或如何找到对应的头文件) 利用Qt Creator开发程序时,需要包含利用#include来添加头文件. 大家都知道,#include <&g ...

  7. VC++ 创建自己的头文件包含GUID

     Guidgen 是比较好用的工具之一,可以使用它来创建ActiveX控件的UUID,同时可以创建独特的剪贴板格式名称和唯一的标识符的内核对象, 如信号量.互斥和事件. 但我需要为另一个目的创建一个唯 ...

  8. 让QT编译快一点(增加基础头文件)

    姚冬,中老年程序员 进藤光.杨个毛.欧阳修 等人赞同 我是来反对楼上某些答案的.我曾经用MFC写了金山词霸(大约20多万行),又用Qt写了YY语音(大约100多万行),算是对两种框架都比较有经验.纠正 ...

  9. VC++中的头文件包含问题

    在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系).也就是需要互相声明.好了,这时候会带来一些混乱.如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已 ...

随机推荐

  1. P5163 WD与地图(整体二分+权值线段树)

    传送门 细节要人命.jpg 这题思路太新奇了--首先不难发现可以倒着做变成加边,但是它还需要我们资瓷加边的同时维护强连通分量.显然加边之后暴力跑是不行的 然后有一个想法,对于一条边\((u,v)\), ...

  2. hdu1325 Is It A Tree? 基础并查集

    #include <stdio.h> #include <string.h> ], g[]; int find(int x) //并查集的查找,找到共同的父亲 { if (f[ ...

  3. 一些CSS的备忘

    text-transform 文本转换 属性值是 none表示没有 不转换 同时也是默认的 capitalize 表示首字母大写 uppercase全部转换为大写 lowercase全部转为小写 te ...

  4. AtCoder Grand Contest 016 E - Poor Turkeys

    题目传送门:https://agc016.contest.atcoder.jp/tasks/agc016_e 题目大意: 有\(N\)只火鸡,现有\(M\)个人,每个人指定了两只火鸡\(x,y\),每 ...

  5. Educational Codeforces Round 20 A

    Description You are given matrix with n rows and n columns filled with zeroes. You should put k ones ...

  6. 【转】javap -c命令详解

    javap -c命令详解 一直在学习Java,碰到了很多问题,碰到了很多关于i++和++i的难题,以及最经典的String str = "abc" 共创建了几个对象的疑难杂症. 知 ...

  7. LN : leetcode 733 Flood Fill

    lc 733 Flood Fill 733 Flood Fill An image is represented by a 2-D array of integers, each integer re ...

  8. 4. iOS测试常用方法

    1.    [XCUIElement exists]方法只能确定这个View是否存在,即使不在当前屏幕上也返回True.如果要确定View是否在屏幕可见范围内,可以判断其Frame是否在Window的 ...

  9. 为sublime Text3 安装插件JS Format

    1. 安装package control 菜单 View - Show Console 或者 ctrl + ~ 快捷键,调出 console.将以下 Python 代码粘贴进去并 enter 执行,不 ...

  10. JS正则匹配待重命名文件名

    <script>var str = "123 - Copy(2).csv";var regExp = /^123( - Copy(\(\d+\))?)?.csv$/;d ...