不能创建从另一个命名空间的类的实例?(Cannot create an instance of a

2019-10-31 14:13发布

好了,所以这是真的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()'

我从来没有遇到过这样的事之前...这只是似乎很奇怪,我甚至不知道任何词/术语来描述这个问题。

我将非常感激任何帮助。

谢谢,

Answer 1:

你的定义B::Tree::Tree()B::Tree::~Tree()声明为inline。 这意味着它们只适用于该源文件,而不是任何其他人。

无论是去除inline自定义,或移动内置定义成需要他们,应该可以解决链接错误所有源文件包含的头文件。



Answer 2:

  namespaceC.cc: undefined reference to `B::Tree::Tree()' namespaceC.cc: undefined reference to `B::Tree::~Tree()' 

那些没有编译器错误 ,它们是链接错误 。 问题是,你声明的构造函数和析构函数,但从来没有定义它们。 所以编译器发现的声明和接受他们,但链接器无法找到定义的引用链接。

这个答案什么是一个声明,什么是一个定义,他们是好什么/需要。



Answer 3:

你必须写在构造函数和析构函数B::Tree的地方串接或者在namespaceB.cc。 通过创建一个实例B ,你需要构造函数和析构函数的存在。



Answer 4:

因为所有的指针都是一样的指针编译罚款。 这只是允许不同的对象类型语义不同。
这本来编译发现,直到您尝试使用它的地步。
但要创建一个实际的对象,你需要的实际定义。

要使用的定义从另一个命名空间,你要么使用范围或使用使用

#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!?
    }
    }


Answer 5:

您声明树的构造和析构函数,但你不告诉我们,你定义它们(你刚才说你实现树namespaceB.cc)

假设您已经定义了它们,你必须确保你既包括namespaceC.o namespaceB.o你的链接线。



Answer 6:

这不是一个命名空间的问题,既不是一个编译器错误。 编译器是幸福的,但连接器无法找到的定义B::Tree::Tree() 您需要提供源文件执行,或者使用-c标志“只是编译”。



Answer 7:

首先,你声明的构造和类的析构Tree自己,这样编译器没有提供默认的实现-你需要自己实现这些功能! (或者只是去掉这些声明...)。

这是不够的,包括头,但你需要明确地说,你正在使用的命名空间从这些标题:

namespaceC.cc添加using namespace B; 之后您有namespace.B ,或者甚至更好,前置类型与命名空间限定词:

B::Tree *tree;    
B::Tree tree;     


Answer 8:

我试图在Visual Studio 2005中的代码如果我删除了“内联”在namespaceB.cc的构造函数和析构函数,它可以在不连接的错误。

然后我发现这个职位: G ++不接受内嵌构造在C ++

它说,内联函数,你必须有它的定义在每个调用该函数的文件。 因此建议把内联定义的头文件。



文章来源: Cannot create an instance of a class from another namespace?