C++ 解决类相互引用导致的编译错误
class Mfun;
class fun
{
public:dosome(){g_mfun.start();}
};
fun g_fun;class Mfun
{
public:void start() {};
};
Mfun g_mfun;
分析:
- 当编译器看到 fun 类的定义时,Mfun 类还没有完全定义,只知道它的名字 g_mfun.start() 需要 Mfun.
- 类的完整定义,但此时只有前向声明. 全局变量的初始化顺序可能导致 g_fun 在 g_mfun 之前初始化 问题分析
- 循环依赖:fun 类中的 dosome() 方法使用了 g_mfun,而 g_mfun 是一个 Mfun 类型的全局变量
- 初始化顺序:全局变量 g_fun 和 g_mfun 的初始化顺序不确定,可能导致 g_fun 在 g_mfun 之前初始化
- 虽然 类前向声明,但是 在编译
dosome(){ g_mfun.start(); }
时,并没有得到类的具体信息,所有编译报错。
解决方案:
1:类成员函数 实现后置
class Mfun; // 前向声明class fun {
public:void dosome(); // 只声明,实现在Mfun定义之后
};
class Mfun {
public:void start() {};
};
// 现在可以完整定义fun的成员函数
void fun::dosome() {g_mfun.start();
}
// 全局变量定义
Mfun g_mfun;
fun g_fun;
这样编码器就能够解析到 类中的成员函数信息(不需要关注具体实现)。
2.使用静态成员函数或单例模式
class Mfun {
public:static Mfun& instance() {static Mfun instance;return instance;}void start() {};
};class fun {
public:void dosome() {Mfun::instance().start();}
};fun g_fun;
3.将实现与声明分离
头文件 fun.h:
class Mfun; // 前向声明
class fun {
public:void dosome();
};
源文件 fun.cpp:
#include "fun.h"
#include "Mfun.h"void fun::dosome() {g_mfun.start();
}// 全局变量
Mfun g_mfun;
fun g_fun;