无法从另一个命名空间创建类的实例?

发布于 2025-01-08 15:37:37 字数 1067 浏览 1 评论 0原文

好吧,这真的很奇怪。我从来没有遇到过这样的事情。

我的程序的一部分(编译失败)包含三个命名空间,如下所示:

// 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()'

我以前从未遇到过这样的事情......这看起来真的很奇怪,我不知道甚至知道任何单词/术语来描述这个问题。

我将非常感谢任何帮助。

谢谢,

Okay, so this is really werid. I've never encountered anything like this.

Part of my program (Fails to compile) contains three namespaces as following:

// 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

Now, g++ went along just fine but the linker ld complains:

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

I have never ever encountered anything like this before... This just seems really weird, I don't even know any words/terms to describe this problem.

I would much appreciate any help.

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

烛影斜 2025-01-15 15:37:37
namespaceC.cc:对“B::Tree::Tree()”的未定义引用
 namespaceC.cc:对“B::Tree::~Tree()”的未定义引用

这些不是编译器错误,它们是链接器错误。问题是您声明了构造函数和析构函数,但从未定义它们。因此,编译器找到声明并接受它们,但是链接器找不到定义来链接引用。

请参阅此答案了解什么是声明以及什么是声明定义以及它们的好处/需要什么。

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

Those are not compiler errors, they are linker errors. The problem is that you declared the constructor and destructor, but never defined them. So the compiler finds the declarations and accepts them, but the linker cannot find the definitions to link the references to.

See this answer for what is a declaration and what is a definition and what they are good/needed for.

奶气 2025-01-15 15:37:37

B::Tree::Tree()B::Tree::~Tree() 的定义被声明为内联。这意味着它们仅在该源文件中可用,而不在任何其他文件中可用。

从定义中删除 inline ,或者将内联定义移动到所有需要它们的源文件包含的头文件中,应该可以修复链接错误。

Your definitions of B::Tree::Tree() and B::Tree::~Tree() are declared inline. This means they are only available in that source file, not any others.

Either removing inline from the definitions, or moving the inline definitions into a header file included by all source files that need them, should fix the link errors.

妞丶爷亲个 2025-01-15 15:37:37

您必须在内联或在 namespaceB.cc 中的某个位置编写 B::Tree 的构造函数和析构函数。通过创建 B 的实例,您需要存在构造函数和析构函数。

You have to write the constructor and destructor for B::Tree somewhere either inline or in namespaceB.cc. By creating an instance of B, you are requiring the existence of the constructor and destructor.

初懵 2025-01-15 15:37:37

该指针编译良好,因为所有指针都是相同的。只是不同对象类型允许的语义不同。
它会编译 find 直到您尝试使用它。
但要创建实际的对象,您需要实际的定义。

要使用其他命名空间中的定义,您可以使用范围,或者使用使用

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

The pointer compiles fine because all pointers are the same. It's just the semantics allowed for different object types differ.
It would have compiled find up until the point you tried to use it.
But to create an actual object, you need the actual definition.

To use definitions from another namespace, you either used scopes, or use using:

#include "namespace.B"
using namespace B;
namespace C {
void run() {
    Tree *tree;    // FINE
    Tree tree;     // Fail to compile!?
}
}

or:

   #include "namespace.B"
    namespace C {
    void run() {
        B::Tree *tree;    // FINE
        B::Tree tree;     // Fail to compile!?
    }
    }
漫漫岁月 2025-01-15 15:37:37

您声明 Tree 构造函数 &析构函数,但您没有向我们展示定义它们的位置(您只是说您在namespaceB.cc中实现了Tree)

假设您已经定义了它们,则必须确保同时包含namespaceC.onamespaceB .o 在你的链接线上。

You declare the Tree constructor & destructor, but you don't show us where you define them (you just say you implement Tree in namespaceB.cc)

Assuming you have defined them, you must ensure you are including both namespaceC.o and namespaceB.o on your link line.

好倦 2025-01-15 15:37:37

这不是命名空间问题,也不是编译器错误。编译器很高兴,但链接器无法找到 B::Tree::Tree() 的定义。您需要提供用于实现的源文件,或使用 -c 标志“仅编译”。

That's not a namespace problem, neither a compiler error. The compiler is happy, but linker fails to find the definition of B::Tree::Tree(). You need to supply the source file for implementation, or use -c flag to "just compile".

雅心素梦 2025-01-15 15:37:37

首先,您自己声明了类 Tree 的构造函数和析构函数,因此编译器没有提供默认实现 - 您需要自己实现它们! (或者只是删除这些声明......)。

包含标头还不够,但您需要明确说明您正在使用这些标头中的命名空间:

namespaceC.cc 中,在包含 namespaceB; 之后添加 using namespace B; code>namespace.B 或者更好的是,在类型前面加上命名空间限定符:

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

First, you declared constructor and destructor of class Tree yourself so compiler didn't provide default implementation - you need to implement them yourself! (Or just remove those declarations...).

It is not enough to include headers but you need to explicitly say that you're using namespaces from those headers:

In namespaceC.cc add using namespace B; after you include namespace.B or, even better, prepend types with a namespace qualifier:

B::Tree *tree;    
B::Tree tree;     
星軌x 2025-01-15 15:37:37

我在 Visual studio 2005 中尝试了这些代码。如果我删除 namespaceB.cc 中构造函数和析构函数的“内联”,它可以毫无错误地链接。

然后我找到了这篇文章: G++ won't Accept inline constructors in C++

它表示对于内联函数,您必须在调用该函数的每个文件中都有其定义。所以建议将内联定义放在头文件中。

I tried the codes in Visual studio 2005. If I remove the "inline" in namespaceB.cc for the constructor and destructor, it can link without errors.

Then I found this post: G++ won't accept inline constructors in C++

it says that for inline functions you must have its definition in every file that calls the function. So it is recommended to put inline definition in header file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文