namespace和作用域运算符

作者:jicanmeng

时间:2014年11月28日


假设我们的程序中使用了两个库,这两个库中都包含了名称为DoSomething()的函数。那么如果调用DoSomething()函数,那么编译器会不知道应该调用哪一个库中的函数,这称为名称冲突(naming collision)。为了解决这样的问题,C++引入了一种机制,称为命名空间(namespace)。将这两个函数分别放入不同的namespace,然后在调用DoSomething()函数的时候指定调用的是哪一个namespace的函数,即可解决此问题。

learncpp.com上是这样描述的:

  1. A namespace defines an area of code in which all identifiers are guaranteed to be unique. By default, all variables and functions are defined in the global namespace.
  2. C++ allows us to declare our own namespaces via the namespace keyword. Anything declared inside a user-defined namespace belongs to that namespace, not the global namespace.

在C++中,定义一个命名空间的格式如下:

namespace [标识符]
{
    成员1:
    成员2:
    ...
}

其中,namespace是C++关键字,标识符用作命名空间的名称。命名空间中的成员可以是变量,函数,结构体,枚举,类,联合,等等。

示例程序如下:

#include <iostream>

namespace Foo
{
    // This DoSomething() belongs to namespace Foo
    int DoSomething(int nX, int nY){
        return nX + nY;
    }
}

namespace Goo
{
    // This DoSomething() belongs to namespace Goo
    int DoSomething(int nX, int nY){
        return nX - nY;
    }
}

int main(void)
{
    using namespace std;
    cout << Foo::DoSomething(4, 3) << endl;
    cout << Goo::DoSomething(4, 3) << endl;
    return 0;
}

对名称空间中的成员的使用有两种方式:

第一种方式是包含了某个namespace的定义后,使用"命名空间名::成员"的方式来引用。其中,"::"称为作用域运算符(scope resolution operator)。拿上例来说,我们在源文件中包含了命名空间Foo的定义后,在后面使用Foo::DoSomething()的方式引用这个DoSomething函数。

第二种方式是包含了某个namespace的定义后,使用"using namespace 命名空间名"的方式来告诉编译器,如果有不认识的标识符,可以在这个空间中进行寻找。其中"using namespace 命名空间名"可以放在程序的最开始,可以放在其它位置。例如上面的例子可以修改成下面的代码:

#include <iostream>

namespace Foo
{
    // This DoSomething() belongs to namespace Foo
    int DoSomething(int nX, int nY){
        return nX + nY;
    }
}

namespace Goo
{
    // This DoSomething() belongs to namespace Goo
    int DoSomething(int nX, int nY){
        return nX - nY;
    }
}

int main(void)
{
    using namespace std;
    using namespace Foo;
    cout << DoSomething(4, 3) << endl;
    cout << Goo::DoSomething(4, 3) << endl;
    return 0;
}

参考资料

  1. <<C++实用教程>> 电子工业出版社 郑阿奇 主编 丁有和 编著 P220
  2. The C++ Tutorial:
    http://www.learncpp.com/cpp-tutorial/711-namespaces/