C ++ - 在您自己的项目中使用您自己的命名空间

时间:2018-04-12 07:58:39

标签: c++ namespaces

让我们说在您自己的项目中,您拥有自己的命名空间。那么你应该如何使用" MyNamespace"在标题/ CPP文件中?

这有效:

namespace MyNamespace{

class MyClass{

    MyClass(MyNamespace::MyClass&) {}
    MyClass(MyNamespace::MyOtherClass&) {}


    MyNamespace::MyClass& operator=(const MyNamespace::MyClass&) {return *this;}

};

inline void someFunc(MyNamespace::MyClass& obj){};

}

这也有效:

namespace MyNamespace{

class MyClass{

    MyClass(MyClass&) {}
    MyClass(MyOtherClass&) {}

    MyClass& operator=(const MyClass&) {return *this;}

};

inline void someFunc(MyClass& obj){};

}

如果我不写'#34; MyNamespace ::"所以它就像我甚至没有使用命名空间,尤其是这条线,如果" MyOtherClass"来自不同的文件:

MyClass(MyNamespace::MyOtherClass&) {}

但是这当然看起来太多了:

MyNamespace::MyClass& operator=(const MyNamespace::MyClass&) {return *this;}

在CPP文件中,我应该使用"使用命名空间MyNamespace;"或"命名空间MyNamespace {"?

3 个答案:

答案 0 :(得分:3)

名称查找从紧邻的范围开始,并传播到逐渐更高的范围,直到找到某些内容。这意味着当您进入名称空间MyNamespace的定义(即{的{​​{1}}和}之间)时,namespace MyNamespace { /*...*/ }中定义的所有名称}可以使用不合格,名称查找将正确找到它们。这也是通常编写代码的最常见方式。

因此,在您的情况下,第二个代码示例(标题为“This works too”的代码示例)是人们通常期望C ++代码的样子。命名空间应该有助于保持名称的唯一性,而不是妨碍它。

请注意,文件(正如您从“其他文件”中写的那样)与此无关,实际上。在命名空间内,您无需限定即可引用该命名空间的成员。在命名空间之外,您通常使用限定来访问命名空间的成员。

例外

有时候,即使您在名称空间中,也可能需要对名称进行限定。如果要在使用非限定名称调用函数时阻止 Argument-Dependent Lookup,则会发生这种情况,函数的名称​​也在与类型关联的名称空间中查找提供的论据(1)。如果您阻止此操作并确保调用命名空间中的函数,请限定其名称。请注意,这主要适用于模板,其中在编写代码时不知道与模板参数关联的名称空间。

如果您遇到歧义,也可能被迫使用资格。如果您使用MyNamespace指令和/或using声明不加区分地“污染”您的命名空间/范围,就会发生这种情况。更好的解决方案是避免使用这种构造来“减少打字”,并且只在你真正想要它们的完整语义时才使用它们。

(1)这允许找到using之类的东西,而不需要在其中一个参数是例如std::operator <<std::cout

答案 1 :(得分:0)

定义名称空间

namespace myNamespace
{
  int a, b;
}

这些变量通常可以在它们的命名空间中使用它们的标识符(a或b)访问,但是如果从myNamespace命名空间外部访问它们,则必须使用scope运算符::来正确限定它们。这就是为什么你的第二个例子正常工作,因为你在定义它的命名空间中使用MyClass

<强>用法

myNamespace::a
myNamespace::b 

使用using

#include <iostream>
using namespace std;

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}

int main () {
  using first::x;
  using second::y;
  cout << x << '\n';
  cout << y << '\n';
  cout << first::y << '\n';
  cout << second::x << '\n';
  return 0;
}

#include <iostream>
using namespace std;

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}

int main () {
  using namespace first;
  cout << x << '\n';
  cout << y << '\n';
  cout << second::x << '\n';
  cout << second::y << '\n';
  return 0;
}

答案 2 :(得分:0)

两个版本都生成相同的可执行文件。在块namespace MyNamespace{}内部,如果它不在命名空间中但在同一命名空间MyNamespace内声明的那些通常可访问的所有内容都可以访问而不必使用::运算符。不过,可以仍然可以使用它。与从班级中访问班级的数据成员this->myDataMember时写myDataMember相同,但您