命名空间问题:前向声明和混合命名空间

时间:2015-01-30 01:42:48

标签: c++ namespaces

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

using MyNameSpace::MyClass;

VS

namespace MyNameSpace {class MyClass;}

两者之后,似乎我现在可以创建一个MyClass对象。有一种方式比另一种更好吗?另外,如果我不这样做,我是否仍然可以通过在每次需要时添加MyNameSpace :: MyClass来引用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"?),如果你在当前范围内找不到名字,你会自动查找一个级别,直到达到全局范围。

我希望这些问题写得好,易懂。希望我可以得到这些问题的一些答案,并开始了解名称空间如何相互作用。

1 个答案:

答案 0 :(得分:1)

using MyNameSpace::MyClass;

using-declaration 将名称MyClass注入当前范围,引用由MyNameSpace::MyClass表示的实体,该实体必须先前已声明过。

namespace MyNameSpace {class MyClass;}

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

  

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

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

  

一种方式比另一方好吗?

他们完全不同的事情。

  

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

如果using MyNameSpace::MyClass;编译(即MyNameSpace::MyClass已声明),则可以执行此操作。否则,你不能。

  

接下来,如果我使用第二个选项转发声明,我是否还需要   #include "MyClass.h"?在我(非常好)的理解中,在C ++中,   你创建头文件,以转发声明类,以便他们   可以在以后使用。所以,如果你已经向前宣布了,你会吗?   还需要包含头文件吗?

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

  

但是,我不明白为什么会出现这个问题。因为我   在我的头文件的顶部声明使用std :: vector,为什么我没有   已经在全球范围内?一个更好的问题可能是:我该怎么说   我在头文件顶部的范围?另外,我   在C ++中思考(并根据这个答案有什么区别   在写“:: namespace :: identifier”和之间   “namespace :: identifier”?,如果你找不到该名称   当前范围,你会自动查找一个级别,直到你达到   全球范围。

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