将类放入命名空间

Posted

技术标签:

【中文标题】将类放入命名空间【英文标题】:Putting classes inside namespaces 【发布时间】:2011-01-10 05:09:06 【问题描述】:

我看到 Qt 在 Ui 接口中放置了一个类,如下所示:

namespace Ui 
    class MainWindow;


class MainWindow : public QMainWindow

    ...

这种方法是否等同于将整个类包含在命名空间中?它确实看起来更干净。

【问题讨论】:

你在 Qt 的什么地方看到了这个?你能提供一个链接吗?它是有效的 C++,但就编译器而言,全局命名空间中的 MainWindowUi 命名空间是不同的类。除非两个 MainWindows 实际上都在 Ui 命名空间内,但你在某个地方错过了它。请注意,命名空间可以拆分为多个文件。 @Insilico 我在创建新的 GUI 项目时看到它。呵呵,我自己也不是很懂代码。 【参考方案1】:

不,在您的示例中,Ui::MainWindow 是与全局命名空间中定义的 MainWindow 类不同的类。

看:

namespace Ui 
    class MainWindow;


class MainWindow


;

int main()

    Ui::MainWindow mw; // fails due to incomplete type

此代码无法编译,因为 Ui::MainWindow 是不完整的类型。

很可能,Qt 代码只是使用了前向声明。您可以在命名空间中前向声明该类,但您仍然必须在同一命名空间中实际实现该类,否则它不是同一个类。

【讨论】:

也就是说,除非 OP 中的类被包装在命名空间声明中(省略代码?)并且命名空间的 MainWindow 声明只是一个前向声明,供其自身和实际的定义......但话又说回来,我很可能超越自己;)+1【参考方案2】:

这两个类是不同的。您所说的不是 Qt 本身,而是使用 Designer 创建 UI 对象的结果。 Qt 这样做是正确的,因为他们试图将生成的代码与您可能添加为逻辑的任何内容(例如信号处理函数等)分开......否则他们必须能够做以下三件事之一:

1) 尝试区分设计师需要修改的内容和用户不希望修改的内容...以他们必须任意想出的某种神秘方式解决冲突。

2) 只需覆盖用户更改的任何内容。

3) 如果用户没有删除文件或其他内容,则不要更改文件。

首先是大量的工作,无论开发人员选择什么,都会给某人、某处带来不便。第二种选择当然会让人们感到不安,因为他们编写的所有插槽代码都会随着 UI 的每次更改而被破坏,这几乎总是非常不方便。出于多种原因,第三个当然不方便。

所以他们所做的是将设计师生成的 UI 对象部分和开发人员/用户编写的部分分开。这允许他们简单地破坏对某些明确定义的区域的更改,同时让开发人员添加他们需要的行为,而不必继续添加它。

这不是您在常规程序设计中通常会做的事情。这样做是为了解决一个与自动生成的代码有关的相当具体的问题。这是一个经过深思熟虑的方法 IMNSHO。

【讨论】:

【参考方案3】:

通常,uic 会生成如下所示的标题:

      class Ui_MainWindow
      
         // auto-generated stuff
      ;

      namespace Ui 
            class MainWindow: public Ui_MainWindow ;
      

这使您可以使用 MainWindow 作为类的名称,并且仍然调用自动生成的 UI 类 MainWindow。请注意,Ui::MainWindow 是完整的类定义,而不是前向声明。

【讨论】:

以上是关于将类放入命名空间的主要内容,如果未能解决你的问题,请参考以下文章

将结构放入匿名命名空间有啥作用? [复制]

如何避免 Rails 脚手架将模型放入命名空间

命名空间和类名冲突

将表单放入命名空间会导致MissingManifestResourceException

为啥 range-v3 将其函数对象放入内联命名空间?

PHP接口和命名空间