在C++中经常会涉及到处于不同头文件的类互相引用的情况,有时候头文件引用(include)会搞得很乱,导致报一堆的错。其实遵循一定规则,可以避免大部分的混乱。
首先,要对头文件进行处理,保证不会出现重定义的错误。这个应该每个人都会,通常有两种做法:
1. 在.cpp文件中添加保护,比如在.cpp文件中添加:
#ifndef _XX_H_
#define _XX_H_
#include "xx.h"
#endif
 
2. 在.h中添加保护,比如在xx.h文件中添加:
#ifndef _XX_H_
#define _XX_H_
// 头文件声明内容
#endif
 
_XX_H_是我比较习惯的命名方式,其他的命名方式,比如__XX__H__,XX_H等等,只要足够Unique就好。建议使用第二种方式进行重定义的保护,一劳永逸而且具有通用性,任何人拿来就能用,不需要考虑保护问题。当然,如果在VS(03以上吧?)下,最好的解决方案是用#pragma once,更为简单有效。
其次,最好将所有头文件需要用到的自定义类(或函数)都在定义前声明一下,比如在xx.h的类xx中需要用到yy.h中的yy类,那么最好做以下的处理:
class yy;
class xx
{
// 实现内容
};
 
这样就可以保证头文件引用的次序不会对结果造成影响。
通常,保证以上两点,通常涉及到类互指的问题都可以解决。当然如果天生就有设计问题,无论如何都是没有办法的,比如:
// xx.h    
class xx
{
yy t;
};
// yy.h
class yy
{
xx t;
};
 
不难看出,这是个递归定义,编译器无法确定类xx和yy的大小,就无法通过编译。一种解决策略是采用指针,比如:
// xx.h    
class xx
{
yy* t;
};
// yy.h
class yy
{
xx* t;
};
 
当然,具体情况具体分析,提取一个更高层的类等手段都可以考虑。
还有一个问题,我一直也心存疑问,就是头文件组织问题。在VS中建立一个MFC工程,都会产生一对stdafx文件,按照这种思想我们把工程下通用的头文件都放入stdafx.h中,在.cpp文件的最开始统一#include "stdafx.h",这样就可以在.h文件中引用很少的头文件。
这种策略在单工程时很好用,相当于做了头文件组织级别的重用,但它违反了我一直恪守的一个原则即谁的头文件谁负责,指.h和.cpp各自负责各自所需的头文件。于是在跨工程的时候会出现一些问题。比如在B工程B的某个.h中引用了工程B中的一个头文件,由于编译次序问题,这个头文件可能无法被编译。不知道大家都如何处理头文件组织问题的,望指教。