简介命名空间


一个应用程序中会有多变量、常数、函数、类彼此合作,也有可能由多个团队共同分工,完成应用程序的某些功能块,再组合在一起。

如果你的应用程序是多个团队共同合作,如果没有定义命名空间,名称默认都是位于全局名域空间,以类定义来说,那么若 A 部门写了个Account类,B 部门写了个Account类,当他们要将应用程序整合时,就会发生名称冲突的问题。

C++ 可以使用namespace来定义命名空间,例如,可以在 account.h 中定义bank命名空间:

account.h

#include <string>

namespace bank {
    using namespace std; 

    class Account { 
    private:
        string id;  
        string name; 
        double balance;

    public: 
        Account(string id, string name, double balance);
        void deposit(double amount);
        void withdraw(double amount);
        string to_string() const;
    };
}

在 account.cpp 可以开启bank命名空间,并在其中实现类定义:

...略
#include "account.h"

namespace bank {
    using namespace std;

    Account::Account(string id, string name, double balance) {
        this->id = id;
        this->name = name;
        this->balance = balance;
    }

    string Account::to_string() const {
        return string("Account(") + 
            this->id + ", " +
            this->name + ", " +
            std::to_string(this->balance) + ")";
    }

    ...略
}

或者是在实现时指定bank范畴:

...略
#include "account.h"

using namespace std;

bank::Account::Account(string id, string name, double balance) {
    this->id = id;
    this->name = name;
    this->balance = balance;
}

string bank::Account::to_string() const {
    return string("Account(") + 
           this->id + ", " +
           this->name + ", " +
           std::to_string(this->balance) + ")";
}
...略

命名空间会是类名称的一部份,因此在使用时,必须包含bank前置:

bank::Account acct = {"123-456-789", "Justin Lin", 1000};
cout << acct.to_string() << endl;

try {
    acct.withdraw(10200);
    acct.deposit(-500);
}
catch(invalid_argument &ex) {
    cout << "实参错误:" << ex.what() << endl;
}
catch(bank::Insufficient &ex) {
    cout << "帐号错误:"  << endl
        << "\t" << ex.what() << endl
        << "\t余额 " << ex.getBalance() << endl;
}

或者是使用using来指明使用哪个命名空间,例如:

...略
using namespace std;
using namespace bank;

int main() {
    Account acct = {"123-456-789", "Justin Lin", 1000};
    cout << acct.to_string() << endl;

    try {
        acct.withdraw(10200);
        acct.deposit(-500);
    }
    catch(invalid_argument &ex) {
        cout << "实参错误:" << ex.what() << endl;
    }
    catch(Insufficient &ex) {
        cout << "帐号错误:"  << endl
            << "\t" << ex.what() << endl
            << "\t余额 " << ex.getBalance() << endl;
    }
}

这也就是为何,至今在使用coutstring等名称前,都会编写using namespace std的原因,这些名称是定义在std命名空间之中,当然,using不可以滥用,不能名称冲突也可能发生,C++ 其实并不建议使用using,多半建议以std::coutstd::string来指明,这系列文件的范例基本上都很小,才会偷懒直接using namespace std


展开阅读全文