【问题标题】:C++ namespaces - forward declaration and visibility of nested namespacesC++ 命名空间 - 嵌套命名空间的前向声明和可见性
【发布时间】:2016-11-02 09:32:24
【问题描述】:

这是一个非常基本的问题,但我实际上从未自己定义过命名空间。我正在尝试将基于 Qt 的库中的类分组到各种命名空间中(并且还允许在没有名称冲突的情况下更轻松地扩展)。例如主类(也代表库)属于顶级命名空间lib

namespace lib {
    class LibClass;
}

这个LibClass 使用了一堆其他名称空间和类,这些名称空间和类定义在LibClass 的头文件中包含的其他头文件中:

#include <QObject>
#include "libclass_global.h"
#include "Manager.h"
#include "Configurator.h"

namespace lib {
    class LibClass;
}

class LIBCLASSSHARED_EXPORT LibClass : public QObject {
    public:
        LibClass();
        ...
    signals:
        ...
    private slots:
        ...
    public slots:
        ...
    private:
        lib::core::communication::Manager manager;             // PROBLEM HERE
        lib::core::communication::Configurator configurator;   // PROBLEM HERE
}

Manager.h 包含

namespace lib {
    namespace core {
        namespace communication {
            class Manager;
        }
    }
}

class Manager {
    public:
        Manager();
        ...
    private:
        ...
}

Configurator.h包含

namespace lib {
    namespace core {
        namespace communication {
            class Configurator;
        }
    }
}

class Configurator {
    public:
        Configurator();
        ...
    private:
        ...
}

类的内容在这里并不重要。

编译后我发现命名空间q3dtp 中的core 没有命名类型。所以基本上据我了解,我需要在 LibClass 的标题中使用前向声明,因为命名空间似乎实际上并未包含在包含这些标题文件的插入中(出于某种原因):

namespace lib {
    class LibClass;

    namespace core {
        namespace communication {
            class Manager;
            class Configurator;
        }
    }
}

问题在于,现在我仅限于指针,因为我在前向声明 ManagerConfigurator。我想尽可能避免动态分配东西(并且不需要)。

所以这里的问题是我该如何解决这个问题?我显然可以将我所有的类声明移动到同一个头文件,并将它们的定义移动到同一个源文件。然而,这将使事情在未来变得相当难以维护。仅声明子命名空间似乎也不能解决问题 - 我知道这两个类都没有命名类型,而且LibClass 没有成员名称&lt;name_of_class_from_nested_namespace&gt;

【问题讨论】:

    标签: c++ namespaces


    【解决方案1】:

    您对LibClass 的声明是错误的。应该是:

    namespace lib {
        class LibClass;
    }
    
    class lib::LibClass {
        ...
    };
    

    namespace lib {
        class LibClass {
            ....
        };
    }
    

    就目前而言,您声明lib::LibClass 并定义::LibClass(两个完全不同的类)。

    这也适用于您的所有其他课程。

    【讨论】:

      【解决方案2】:

      当你这样做时

      namespace ns {
        class cls;
      };
      
      class cls {
      };
      

      你先声明一个类型,然后再定义另一个。您需要限定类名:

      namespace ns {
        class cls;
      };
      
      class ns::cls {
      };
      

      随着 c++17 的出现,如果这对于嵌套命名空间来说变得过于繁琐,您可以执行以下操作:

      namespace ns1::ns2::ns3 {
      
        class cls {
        };
      
      }
      

      【讨论】:

        猜你喜欢
        • 2011-09-20
        • 2011-03-02
        • 2015-03-29
        • 2012-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-14
        相关资源
        最近更新 更多