首先阐明一点,交叉引用和extern的使用之间并没有必然的联系,只是我在解决一个问题的时候,引出了这两个问题,所以一起分析一下
阐明一下我的问题:
有三个文件:
(1)StdAfx.h 文件中定义了CServiceModule这个类,还有extern CServiceModule _Module的声明,同时在此类中还有一个PrintJobQueue的对象;
#include 'PrintJobQueue.h'
class CServiceModule
{
PrintJobQueue m_PrintQueue;
......
};
extern CServiceModule _Module;
(2)StdAfx.cpp 文件中定义了CServiceModule的对象
#include 'StdAfx.h'
CServiceModule _Module;
(3)PrintJobQueue.h 文件中定义了PrintJobQueue这个类,其中需要使用数据库的链接指针,此指针定义在StdAfx.h的CServiceMoudle类中
class PrintJobQueue
{
CString strSql = "......";
_Moudle.m_pSqlConn.excute(strSql);
......
};
好了,这就是我说的三个文件,这时,编译整个工程,报错error C2065: :’ _Moudle‘ undeclared identifier,可是_Moudle明明是全局变量,不能使用不合理啊
于是将PrintJobQueue.h文件做了如下修改:
#include 'StdAfx.h'
extern CServiceModule _Module;
class PrintJobQueue
{
CString strSql = "......";
_Moudle.m_pSqlConn.excute(strSql);
......
};
编译,报错,error C2065: :’ _Moudle‘ undeclared identifier,为什么,细看了一下,发现PrintJobQueue.h和StdAfx.h进行了重复包含,这样就进入了一个死循环,出不来了,这就是交叉引用,在写代码的时候一定要尽量避免出这样的错误,将代码恢复到之前的位置,问题依旧没有解决
怎么办,最后,将数据库的指针定义为全局变量,再在PrintJobQueue.h这个头文件中使用,编译成功,修改后的代码如下:
(1)StdAfx.h
#include 'PrintJobQueue.h'
class CServiceModule
{
PrintJobQueue m_PrintQueue;
......
};
extern CServiceModule _Module;
(2)StdAfx.cpp
#include 'StdAfx.h'
CServiceModule _Module;
CADODatabase* g_pSqlConn;
(3)PrintJobQueue.h
extern CADODatabase* g_pSqlConn;
class PrintJobQueue
{
CString strSql = "......";
g_pSqlConn.excute(strSql);
......
};
接下来说一说extern和全局变量
结合上面的代码总结如下:(此处是转载的)
文件中定义的全局变量的可见性扩展到整个程序是在链接完成之后,而在编译阶段,他们的可见性仍局限于各自的文件。
编译器的目光不够长远,编译器没有能够意识到,某个变量符号虽然不是本文件定义的,但是它可能是在其它的文件中定义的。
虽然编译器不够远见,但是我们可以给它提示,帮助它来解决上面出现的error C2065: :’ _Moudle‘ undeclared identifier问题。这就是extern的作用了。
extern的原理很简单,就是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!”