C++ 名称空间

名称空间的基本定义和使用 

#include <iostream>

using namespace std;

namespace my_std
{
    int a;
    int b;
}
int a;

void show1();
int main()
{
    int a;//局部的同名变量将全局的同名变量隐藏,可以说优先级最高

    cout << "please input local a " << endl;
    cin >> a;
    cout << "please input global a " << endl;
    cin >> ::a;
    cout << "please input namespace a " << endl;
    cin >> my_std::a;
    cout << "local a is " << a << endl;
    cout << "global a is " << ::a << endl;
    cout << "namespace a is " << my_std::a;
    show1();
    return 0;
}

//using my_std 在这里可以;不过在函数中使用并且函数中有同名变量的情况下还是要使用::
void show1()
{
    //using namespace my_std 可以在函数中使用,不过同名局部变量还是要加上::
    //using my_std::b; //不能在函数中 和函数中的局部同名变量声明冲突
    int b;
    cout << "\nplease b in function " << endl;
    cin >> b;
    cout << "please input namespace b " << endl;
    cin >> my_std::b;
    cout << "local b in function is " << b << endl;
    cout << "namespace b is " << my_std::b << endl;
}

对于using 声明 和 using 编译C++ Primer Plus 给出了如下指导

一般来说 ,使用using声明比使用using编译指令更安全,这是由于他只导入指定的名称。如果该名称与局部名称发生冲突,编译器将发出警告。using编译指令导入所有名称,包括可能并不需要的名称。如果与局部名称发生冲突,则局部名称将覆盖名称空间版本,而编译器不会发出警告。另外,名称空间的开房意味着名称空间的名称可能分散在多个地方,这使得难以准确的知道添加了哪些名称

using namesspace std;         //avoid sa too indiscriminate

应该这样做 std::cin >> something;

或者这样做 using std::cin;        cin >> someting;

事实上,在CLion下也确实给出了警告

Declaration shadows a variable in namespace 'my_std'

声明隐藏命名空间'my_std'中的变量

名称空间的嵌套

#include <iostream>

using namespace std;
namespace MyNamespace_3
{
    int _3_a = 31;
    int _3_b;
}

namespace MyNamespace_2
{
    int _2_a = 21;
    int _2_b = 22;
}

namespace MyNamespace_1
{
    int _1_a = 11;
    namespace MyNamespace_1_1
    {
        int _1_1_a = 111;
        int _1_1_b = 112;
    }
    using namespace MyNamespace_2;
    using MyNamespace_3::_3_a;

}

int main()
{
    //访问_1_a
    cout << MyNamespace_1::_1_a << endl;

    //访问_1_1_a and _1_1_b
    cout << MyNamespace_1::MyNamespace_1_1::_1_1_a << " " << MyNamespace_1::MyNamespace_1_1::_1_1_b << endl;

    //访问_2_a and _2_b 的两种方法
    cout << MyNamespace_1::_2_a << " " << MyNamespace_1::_2_b << endl;
    cout << MyNamespace_2::_2_a << " " << MyNamespace_2::_2_b << endl;

    //访问 _3_a 的两种方法
    cout << MyNamespace_1::_3_a << endl;
    cout << MyNamespace_3::_3_a << endl;

    //可以通过 = 给一个名称空间取别名

    namespace MY_11 = MyNamespace_1::MyNamespace_1_1;
    cout << MY_11::_1_1_a << " " << MyNamespace_1::MyNamespace_1_1::_1_1_b << endl;
    
    //using namespace MY_11 // OK
    //using MY_11::_1_1_a   // OK
    return 0;
}

 名称空间具有 op 传递性质

假如myth 嵌套了 elements 那么以下两种using 编译指令是相同的

1.using namespace myth;

2.using namespace myth;

   using namespace elements;

未命名的名称空间

namespace 
{
    int a;
    int b;
    int c;
}

因为其没有名称,所以不可以显示的用using 编译指令或者是using 声明

具有内部连接属性

这提供了连接性为内部的静态变量的替代品

static int a;
static int b;
static int c;

可以替换为上面的未命名的名称空间

名称空间的具体使用案例

输入人名和欠款并计算总共的欠款

并将任命和欠款打印到屏幕上

C++ Primer Plus P271 ~ P273 源代码

namesp.h

#ifndef C___NAMESP_H
#define C___NAMESP_H

#include <string>

namespace pers
{
    struct Person
    {
        std::string fname;
        std::string lname;
    };
    void getPerson(Person &);
    void showPerson(const Person &);
}

namespace debts
{
    using namespace pers;
    struct Debt
    {
        Person name;    //name is a struct
        double amount;
    };
    void getDebt(Debt &);
    void showDebt(const Debt &);    //注意这里的const 修饰
    double sumDebts(const Debt[], int n);
}
#endif //C___NAMESP_H

namesp.cpp

#include <iostream>
#include "namesp.h"

namespace pers
{
    using std::cin;
    using std::cout;
    void getPerson(Person &rp)
    {
        cout << "Enter first name : ";
        cin >> rp.fname;
        cout << "Enter last name : ";
        cin >> rp.lname;
    }
    void showPerson(const Person &rp)
    {
        std::cout << rp.lname << ", " << rp.fname ;
    }
}

namespace debts
{
    void getDebt(Debt &rd)
    {
        getPerson(rd.name);  //这个name是一个Person 结构体
        std::cout << "Enter debt: ";
        std:: cin >> rd.amount;
    }
    void showDebt(const Debt &rd)
    {
        showPerson(rd.name);
        std::cout << ": $ " << rd.amount << std::endl;
    }
    double sumDebts(const Debt ar[], int n)
    {
        double total = 0;
        for (int i = 0; i < n; ++i) {
            total += ar[i].amount;
        }
        return total;
    }
}

main.cpp

#include <iostream>
#include "namesp.h"
using namespace std;

void other();
void another();
int main()
{
    using debts::Debt;  //struct
    using debts::showDebt; //这里函数名即可
    Debt golf ={{"Benny", "Goatsniff"},120.0};
    debts::showDebt(golf);
    other();
    another();
    return 0;
}

void other()
{
    using std::endl;
    using std::cout;
    using namespace debts;
    Person dg = {"Doodles", "Glister"};
    showPerson(dg);
    cout << endl;
    Debt zippy[3];
    int i;
    for(i = 0; i < 3; i++){
        getDebt(zippy[i]);
    }
    for(i = 0; i < 3; i++){
        showDebt(zippy[i]);
    }
    cout << "Total debt : $" <<sumDebts(zippy,3) << endl;
}

void another()
{
    using pers::Person;
    Person collector = {"Milo", "Rightshift"};
    pers::showPerson(collector);
    std::cout << std::endl;
}

对于《C++ Primer Plus》给出的命名空间指导原则,见《C++ Primer Plus》P274

这里对其进行简述

1.尽量用名称空间中声明的变量,而不是使用外部全局变量或者静态全局变量,这也是OPP编程思想的一种体现

2.不在头文件中使用using 编译指令

3.导入名称时,首选::运算符或者using声明

4.对于using声明,首选将其作用域设置在局部而不是全局

5.对于只有一个文件的程序来说,使用using并非什么大逆不道的事情

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值