好了,所以这是真的werid。 我从来没有遇到过这样的事。
我的计划的一部分(编译失败)包含三个命名空间如下:
// namespaceA.h
namespace A {
enum Kind { jimmy, david };
}
// end of namespaceA.h
// namespaceB.h
#include "namespaceA.h"
namespace B {
class Tree {
public:
Tree *prev;
Tree *next;
Tree *down;
A::Kind kind;
Tree();
~Tree();
};
}
// end of namespaceB.h
// Implementation details of the class are placed in namespaceB.cc
// Constructor / Desctructor defined in the namespaceB.cc file!
// Something like this,
#include "namespaceB.h"
namespace B {
inline Tree::Tree() { ... }
inline Tree::~Tree() { ... }
}
// namespaceC.cc
#include "namespace.B"
namespace C {
void run() {
B::Tree *tree; // FINE
B::Tree tree; // Fail to compile!?
}
}
// end of namespaceC.cc
现在,G ++就跟着去了就好了,但连接器ld抱怨:
"namespaceC.cc: undefined reference to `B::Tree::Tree()'
"namespaceC.cc: undefined reference to `B::Tree::~Tree()'
我从来没有遇到过这样的事之前...这只是似乎很奇怪,我甚至不知道任何词/术语来描述这个问题。
我将非常感激任何帮助。
谢谢,
你的定义B::Tree::Tree()
和B::Tree::~Tree()
声明为inline。 这意味着它们只适用于该源文件,而不是任何其他人。
无论是去除inline
自定义,或移动内置定义成需要他们,应该可以解决链接错误所有源文件包含的头文件。
namespaceC.cc: undefined reference to `B::Tree::Tree()' namespaceC.cc: undefined reference to `B::Tree::~Tree()'
那些没有编译器错误 ,它们是链接错误 。 问题是,你声明的构造函数和析构函数,但从来没有定义它们。 所以编译器发现的声明和接受他们,但链接器无法找到定义的引用链接。
见这个答案什么是一个声明,什么是一个定义,他们是好什么/需要。
你必须写在构造函数和析构函数B::Tree
的地方串接或者在namespaceB.cc。 通过创建一个实例B
,你需要构造函数和析构函数的存在。
因为所有的指针都是一样的指针编译罚款。 这只是允许不同的对象类型语义不同。
这本来编译发现,直到您尝试使用它的地步。
但要创建一个实际的对象,你需要的实际定义。
要使用的定义从另一个命名空间,你要么使用范围或使用使用 :
#include "namespace.B"
using namespace B;
namespace C {
void run() {
Tree *tree; // FINE
Tree tree; // Fail to compile!?
}
}
要么:
#include "namespace.B"
namespace C {
void run() {
B::Tree *tree; // FINE
B::Tree tree; // Fail to compile!?
}
}
您声明树的构造和析构函数,但你不告诉我们,你定义它们(你刚才说你实现树namespaceB.cc)
假设您已经定义了它们,你必须确保你既包括namespaceC.o 和 namespaceB.o你的链接线。
这不是一个命名空间的问题,既不是一个编译器错误。 编译器是幸福的,但连接器无法找到的定义B::Tree::Tree()
您需要提供源文件执行,或者使用-c
标志“只是编译”。
首先,你声明的构造和类的析构Tree
自己,这样编译器没有提供默认的实现-你需要自己实现这些功能! (或者只是去掉这些声明...)。
这是不够的,包括头,但你需要明确地说,你正在使用的命名空间从这些标题:
在namespaceC.cc
添加using namespace B;
之后您有namespace.B
,或者甚至更好,前置类型与命名空间限定词:
B::Tree *tree;
B::Tree tree;
我试图在Visual Studio 2005中的代码如果我删除了“内联”在namespaceB.cc的构造函数和析构函数,它可以在不连接的错误。
然后我发现这个职位: G ++不接受内嵌构造在C ++
它说,内联函数,你必须有它的定义在每个调用该函数的文件。 因此建议把内联定义的头文件。