如何使用命名空间内单独标头中定义的类

Posted

技术标签:

【中文标题】如何使用命名空间内单独标头中定义的类【英文标题】:How to use class defined in a separate header within a namespace 【发布时间】:2012-01-06 16:05:24 【问题描述】:

我有一个命名空间,我想在其中定义一个类。这个类相当复杂,所以我宁愿在单独的头文件中定义它,但即使是最简单的代码也会给我一个“未定义的引用”错误。

main.cpp

#include <iostream>
namespace A 
    #include "C.hpp"


int main()

    A::C foo;
    std::cout << foo.member << std::endl;
    return 0;

C.hpp

class C 
    public:
     C();
     int member;

C.cpp

C::C()

    this->member = 10;

当我运行g++ C.cpp main.cpp 时,我得到“main.cpp:(.text+0x10): undefined reference to `A::C::C()'”错误。我想这是构造函数的 C::C() 定义有点错误,但我不确定如何修复它。

【问题讨论】:

你的定义是错误的...... 我假设您已经这样做了,因为您遇到了命名冲突。在这一点上,我只想说:“我希望您已经吸取了有关在创建类时忽略名称空间的教训。 【参考方案1】:

您也必须在命名空间A 中定义C 的构造函数:

namespace A

    C::C()
    
        this->member = 10;
    

【讨论】:

因此,您必须预先确定该类属于哪个命名空间。没有来自一个用户的namespace A #include "C.hpp" 和来自另一个用户的namespace B #include "C.hpp" 。除非类及其成员完全在标题中定义,尽管我也不建议这样做,因为这两个用户最终会得到两个恰好具有相同定义的不同类。如果用户不喜欢类作者选择的命名空间,他们可以写namespace A typedef HorridNamespace::C C; namespace A using HorridNamespace::C; 我明白了。所以我要么必须在标题中定义整个类,要么将其包含在命名空间之外?如果类在命名空间之外没有多大用处,那么什么被认为是更好的方法? @Steve: 或者干脆namespace A = HorridNamespace 确实,如果你想要命名空间的全部内容。 @user1134621:更好的方法是您应该永远在命名空间内写入#include。 “从不”的意思是,“除非你正在做一些我没有想到的非常晦涩的事情并且证明它是合理的”。您希望能够查看文件,并查看其中所有内容的完全限定名称。如果有人稍后出现并通过从他们的命名空间中包含一个额外的命名空间,你就不能这样做。【参考方案2】:
namespace A 
    #include "C.hpp"

这是一件很奇怪的事情。

这会将标头中声明的所有内容放在名为 A 的命名空间中;具体来说,它为您提供A::C 的声明,它与您在包含没有周围命名空间的标头时获得的::C 不同。

您提供了::C::C() 的定义;但是main.cpp 需要A::C::C() 的定义,因为这是它使用的类。这在任何地方都没有定义,因此会出现错误。

通过将命名空间移动到头文件(并修复 C.cpp 以使用该命名空间)将 C 正确放入 namespace A,或者删除 namespace A

【讨论】:

以上是关于如何使用命名空间内单独标头中定义的类的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个 C++ 命名空间内的全局命名空间中定义朋友?

如何在(子)模块中使用 __init__.py 来定义命名空间?

命名空间内的类定义

删除 Soap 标头和命名空间

thinkphp5.0 中使用第三方无命名空间的类库

如何在 C++ 中正确使用命名空间?