名称空间的基本定义和使用
#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并非什么大逆不道的事情