我正在努力帮助同事编译一些东西 - 实际上,他试图减少我们需要从一个更大的软件系统制作的小型可执行文件的依赖性。
我不确定我是否可以完全解释这个问题,因为我并不完全理解它...但是我将展示这里发生了什么:
图书馆A:档案:A.h
namespace CF {
typedef sometype B;
};
图书馆C:档案C.h
//Forward declare Class
class CF::B;
Class D {
public:
B* UseB();
};
图书馆C:档案C.cpp
#include "C.h"
#include "A.h"
using CF::B;
B* D::UseB()
{
return new B;
}
抱歉,我知道这看起来有点疯狂,但我试图从我们实际处理的文件集中简化它。
我们通常会在CF :: B上遇到多重定义错误,或者当我们使用代码并更改它时,有时在CPP文件中它只是无法识别CF :: B的类型。
我想我的第一个问题是......我可以转发声明我们尝试过的typedef,还是有其他方法来处理B是CF命名空间中的typedef这一事实,我们不想要它直接包含在Ch文件中?
答案 0 :(得分:2)
这可能对您有所帮助:
A.H:
#ifndef NAMESPACE_A
#define NAMESPACE_A
namespace A
{
class B
{
public: int i;
};
}
#endif
c.h:
#ifndef NAMESPACE_A
#define NAMESPACE_A
namespace A
{
class B;
}
#endif
class D
{
public:
A::B* UseB();
};
main.cpp中:
#include "a.h"
#include "c.h"
using A::B;
B* D::UseB()
{
return new B();
}
int main(int argc, char* argv[])
{
D* d = new D();
B* b = d->UseB();
b->i = 1;
return 0;
}
......对我来说很好;)
答案 1 :(得分:1)
前瞻声明更像是
namespace CF { class B; }
编译器无法从CF::B
中创建任何内容,除非它已经知道CF是命名空间。
您也无法转发声明typedef,因为编译器必须知道B是类还是内置类型。某些内置类型具有特殊规则,例如char*
或void*
。