【问题标题】:Namespace questions: forward declaration and mixing namespaces命名空间问题:前向声明和混合命名空间
【发布时间】:2015-03-29 11:01:37
【问题描述】:

我对 C++ 不是很熟悉,这是我第一次使用不仅仅是命名空间 std。以下有什么区别?

using MyNameSpace::MyClass;

namespace MyNameSpace {class MyClass;}

在两者之后,我现在似乎可以创建一个 MyClass 对象。一种方式比另一种更好吗?另外,如果我不这样做,我是否仍然可以通过在每次需要时在 MyClass 之前附加 MyNameSpace::MyClass 来引用它?

接下来,如果我使用第二个选项转发声明,我还需要#include "MyClass.h"吗?在我(不是很好)的理解中,在 C++ 中,您制作头文件是为了转发声明类,以便以后可以使用它们。那么如果已经前向声明了,还需要包含头文件吗?

最后,当使用多个命名空间(namespace Architecturenamespace Router)时,我遇到了一个不知道如何解释的错误。在我的一个头文件中,我将using std::vector 作为#include 语句之后的第一行。我认为,此语句不在任何名称空间内。编译时,我收到错误消息“'Architecture::std::vector' 尚未声明”。为了解决这个问题,我可以将语句更改为 using ::std::vector 以告诉它查看 std::vector 的全局范围。

但是,我不明白为什么会出现这个问题。既然我在头文件的顶部声明了using std::vector,为什么我还没有在全局范围内?一个更好的问题可能是:如何判断我在头文件顶部的哪个范围?此外,我认为在 C++ 中(并根据此答案 What is the difference between writing "::namespace::identifier" and "namespace::identifier"?),如果在当前范围内找不到名称,则会自动查找级别,直到达到全局范围。

我希望这些问题写得很好并且易于理解。希望我能得到这些问题的一些答案,并开始了解命名空间之间的交互方式。

【问题讨论】:

  • namespace MyNameSpace {MyClass;} 不是合法的 C++,所以我不确定你想在那里做什么。
  • 哎呀,对不起。我错过了 class 关键字。 namespace MyNameSpace { class MyClass;}
  • 您的第三个问题听起来像是您不小心在Architecture 命名空间中包含了一个标准标头,和/或忘记关闭该命名空间。要么就是你自己在Architecture 中声明了一个名为std 的命名空间或类。检查您的标题是否缺少大括号。
  • 我实际上在几乎所有文件中都包含了一堆标准库,例如#include <vector>。这就是你的意思吗,这就是导致问题的原因吗?

标签: c++ namespaces


【解决方案1】:
using MyNameSpace::MyClass;

using-declaration 将名称MyClass 注入当前作用域,指的是MyNameSpace::MyClass 表示的实体,该实体必须是先前声明的。

namespace MyNameSpace {class MyClass;}

这是命名空间 MyNamespace 中类 MyClass 的前向声明。

在两者之后,我现在似乎可以创建一个 MyClass 对象。

在第二种情况下不太可能,除非您有 using namespace MyNamespace; 并且可以使用 MyClass 的完整定义。

一种方式比另一种更好吗?

他们做的事情完全不同。

另外,如果我不这样做,我是否仍然可以在每次需要时通过在 MyNameSpace::MyClass 前面附加 MyClass 来引用它?

如果using MyNameSpace::MyClass; 编译(即MyNameSpace::MyClass 已被声明),那么您可以这样做。否则,你不能。

接下来,如果我使用第二个选项转发声明,我还需要 #include "MyClass.h"?在我(不是很好)的理解中,在 C++ 中, 您制作头文件以转发声明类,以便它们 以后可以使用。所以如果你已经提前声明了,你会 还需要包含头文件吗?

标头通常带有完整的类定义——包括其所有数据成员和成员函数的声明。像class MyClass; 这样的前向声明将不允许您创建MyClass 对象,因为编译器不知道要为该对象分配多少内存或可用的构造函数。

但是,我不明白为什么会出现这个问题。既然我是 在我的头文件顶部声明使用 std::vector,为什么我不 已经在全球范围内?一个更好的问题可能是:我怎么知道 我在头文件顶部的哪个范围?另外,我 用 C++ 思考(根据这个答案有什么区别 在写“::namespace::identifier”和 "namespace::identifier"?,如果您在 当前范围,您将自动查找一个级别,直到您达到 全局范围。

这听起来像是缺少大括号的问题。如果您编写的标头没有关闭namespace Architecture,那么您在该标头之后包含的任何内容都将被意外放入Architecture 命名空间。如果这不是问题,请发帖MCVE

【讨论】:

  • 我想我明白第一点。 using MyNameSpace::MyClass 只是让我在我的代码中使用MyClass 代替MyNameSpace::MyClass。我想澄清一下关于头文件的观点。如果我使用#include "../Headers/my_class.h",是否有任何理由转发声明namespace MyNameSpace { class MyClass; }
  • @Teofrostus 如果您的标头包含完整的类定义,则无需提供额外的前向声明。
猜你喜欢
  • 1970-01-01
  • 2011-09-20
  • 2011-03-02
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 2012-12-27
  • 1970-01-01
相关资源
最近更新 更多