提问者:小点点

C++命名空间-嵌套命名空间的前向声明和可见性


这是一个非常基本的问题,但实际上我从来没有自己定义过名称空间。我正在尝试将我的基于Qt的库中的类分组在各种名称空间中(并且还允许更容易的扩展而不发生名称冲突)。例如,主类(也表示库)属于顶级命名空间lib:

namespace lib {
    class LibClass;
}

这个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没有成员名


共2个答案

匿名用户

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

namespace lib {
    class LibClass;
}

class lib::LibClass {
    ...
};

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

目前,您正在声明lib::libclass和定义::libclass(两种完全不同的类)。

这也适用于你的其他类。

匿名用户

当你做的时候

namespace ns {
  class cls;
};

class cls {
};

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

namespace ns {
  class cls;
};

class ns::cls {
};

随着C++17的出现,如果这对于嵌套名称空间来说太麻烦了,您可以执行以下操作:

namespace ns1::ns2::ns3 {

  class cls {
  };

}

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++|命名|空间|嵌套|命名|空间|前|声明|见性)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?