通常,现在写代码时都会随手在头文件中加入头文件保护符。有以下两种形式的保护符。
#ifndef ABCDE#define ABCDE//..... 内容#endif#PRagma once两种模式的作用是相同的,都是只让头文件在解析过程中只会展开一次。能工作的循环包含情况
今天遇到的问题是循环包含问题,也就是说如下例子
//********************************* a.h 文件#pragma once#include <iostream>#include "b.h"using namespace std;int a = 1;//********************************* b.h文件#pragma once#include "a.h"int b = 1;这是虽然有循环包含,但是由于有头文件保护符的作用,则两者之间是不冲突的,假设存在以下cpp文件:#include "a.h"#include "b.h"int main(){ cout << a << endl; cout << b << endl;}根据 cpp 文件中包含的头文件的顺序,则该cpp 文件会被展开为如下情况://-----------------------------------#include "a.h"#include <iostream>//----------------------#include "b.h"int b = 1;//----------------------using namespace std;int a = 1;//------------------------------------int main(){ cout << a << endl; cout << b << endl;}可以看出,该代码的使用完全没有问题、
出错的循环包含情况
但是如果出现以下这种情况,则循环包含会出错,且报错都是编译解析错误,即分号错误,<号错误等毫无问题的错误。
//**************************************** a.h 文件#pragma once#include "b.h";#include <iostream>using namespace std;class A {};//*************************************** b.h 文件#pragma once#include "a.h"class B { A * aptr;};cpp文件如下:
#include "a.h"#include "b.h"int main() {}此时报错就比较迷离了。会出现错误如下:
错误 C2143语法错误: 缺少“;”(在“*”的前面)Project2d:/文档/visual studio 2015/projects/project2/project2/b.h5
错误 C2238意外的标记位于“;”之前Project2d:/文档/visual studio 2015/projects/project2/project2/b.h5
分析时尝试将两个头文件展开在cpp文件中,展开结果如下
//------------------------#include "a.h"//-----------#include "b.h"class B{ A * aptr;};//------------#include <iostream>using namespace std;class A{};//---------------------------int main(){}此时可以明显看出,问题出现在,当将头文件按其各自在cpp中声明的顺序展开时,会出现在 class B 中,类型 A 未经过声明就使用了的情况。
这个问题难在三个点上:
1. 编译器报错的地方很奇怪,说是分号错误类似的问题,根本无从定位2. 这个问题在包含顺序变动后很可能就消失了,但是弊端还是存在的。假设上例中 cpp 文件先包含 b.h 再包含 a.h ,则就没有问题
3. 若是不止两个头文件间发生了循环包含,而是多个头文件循环包含,则问题更难定位。如 a 包含 b,b 包含 c,c 包含 a,则比较隐晦。
反思
说明:通常在面向对象编程中,我们在头文件中都是定义类,若两个头文件包含,则说明两个头文件中包含的两个类之间关系高度耦合。即A 需要 B , B 需要 A。依照《重构》中的思想,这种情况属于代码臭味,需要考虑将这两个类中的内容合并为一个类,之后将不存在循环包含的情况。类之间通常是单向依赖关系,双向依赖关系意味着臭味,需要对代码进行拆分重组,因此当出现循环包含时,应当考虑代码重构。
转载请标明出处:http://blog.csdn.net/virtual_func
新闻热点
疑难解答
图片精选