学习使用C++的namespace

Last Updated: 2023-12-23 12:04:53 Saturday

-- TOC --

C语言很简单,它只有一个默认的全局命名空间,确实有符号名称冲突的潜在问题。而C++通过显式定义不同namespace的方式来解决符号名冲突的问题。

定义namespace,可包含变量和函数接口,可随时添加成员

using namespace std;

namespace A {
    int a = 100;
}

namespace B {
    int a = 200;

    void func() { //可直接访问 a
        cout << "func is running." << a << endl;
    }
}

// namespace是开放的,可以在代码需要的地方,随时添加成员:
// 将变量c添加到前面有过定义的命名空间A中
namespace A {
    int c = 300;
}

void test02()
{
    // :: 域选择符
    cout<<"A中a = "<<A::a<<endl;//100
    cout<<"B中a = "<<B::a<<endl;//200
    B::func();
}

定义在namespace中的函数接口,可以只把申明放在namespace中,函数的body,可以放在外面定义:

$ cat cpp1.cpp
#include <iostream>
using namespace std;

namespace B {
    int a = 201;
    void func();
}

void B::func() {  // 依然可以直接访问变量a
    cout << "func is runing. a = " << a << endl;
}

int main(void) {
    B::func();
    return 0;
}

从这个角度看,class/struct也是一个namespace,只是这个空间,只有一个type的定义。

namespace只能在全局范围内定义,但可嵌套

不能在某个函数接口的定义中定义namespace。

using namespace std;

namespace A {
    int a = 1000;

    namespace B {
        int a = 2000;
    }
}

void test03()
{
    cout<<"A中的a = "<<A::a<<endl; //1000
    cout<<"B中的a = "<<A::B::a<<endl; //2000
}

另一种更succint的namespace嵌套方式:

namespace BroopKidron13::Shaltanac {
    // All symbols declared within this block
    // belong to the BroopKidron13::Shaltanac namespace
}

class/struct的定义也可以嵌套。

无名namespace,意味着namespace中的符号只能在当前文件中访问,相当于给这个namespace加上了static

由于namespace没有名称,访问其中的符号也就不需要::符号了,直接用其名称。

#include <iostream>

namespace {
    int a = 1;
    int b = 2;
}

int main(void) {
    std::cout << "hi..." << a << " " << b << std::endl;
    return 0;
}

输出:

$ g++ -Wall -Wextra test_4.cpp -o 4
$ ./4
hi...1 2

namespace可以有alias name

$ cat cpp2.cpp
#include <iostream>
using namespace std;


namespace ABCDEFG {
    int a = 201;
}

namespace efg = ABCDEFG;

int main(void) {
    namespace abc = ABCDEFG;
    cout << abc::a << endl;
    cout << ABCDEFG::a << endl;
    ::cout << efg::a << endl;  //  ::cout与直接用cout一样
    return 0;
}

using就有点像Python的star import,将某个namespace中的所有符号名称引入当前文件。

域选择符::

用using引入namespace

用using引入namespace中的符号

本文链接:https://cs.pynote.net/sf/c/cpp/202205061/

-- EOF --

-- MORE --