名称空间
(1) 传统的C++名称空间。
术语:
1. 声明区域(declaration region): 可以在其中进行声明的区域。 例如,可以在函数外面声明全局变量,对于这种变量,其声明区域为其声明所在的文件中。对于在函数中声明的变量,其声明区域为其声明所在的代码块。
2. 潜在作用域(potential scope): 变量的潜在作用域从声明点开始,到其声明区域的结尾。 因此潜在作用域比声明区域小,这是由于变量必须定义后才能使用。
3. 作用域(scope): 变量对程序而言可见的范围被称为作用域。
(2) 新的名称空间特性。
C++新增功能:通过定义一种新的声明区域来创建命名的名称空间。
例如,下面代码使用新的关键字namespace创建了两个名称空间:Jack和Jill。
namespace Jack {
double pail; //变量声明
void fetch(); //函数原型
int pal; //变量声明
struct Well{...}; //结构声明
}
namespace Jill {
double bucket(double n){...} //函数定义
double fetch; //变量声明
int pal; //变量声明
struct Hill{...}; //结构声明
}
名称空间可以是全局的,也可以位于另一个名称空间中,但不能位于代码块中。 因此,在默认情况下,在名称空间中声明的名称的链接性为外部的。
名称空间是开放的,即可以把名称加入到已有的名称空间中。例如,下面这条语句将名称goose添加到Jill中已有的名称列表中:
namespace Jill {
char * goose(const char *);
}
同样,原来的Jack名称空间为fetch()函数提供了原型。可以在该文件后面(或另外一个文件中)再次使用Jack名称空间来提供函数的代码:
namespace Jack {
void fetch()
{
...
}
}
当然,需要有一种方法来访问给定名称空间中的名称。 最简单的方法是,通过作用域解析运算符::,使用名称空间来限定该名称。
Jack::pail = 12.34; //使用一个变量
Jill::Hill mole; //创造一个Hill类型结构
Jack::fetch(); //使用一个函数
using声明和using编译指令
using声明使特定的标识符可用,using编译指令使整个名称空间可用。
using声明由被限定的名称和它前面的关键字using组成:
例如:using Jill::fetch;
using编译指令由名称空间名和它前面的关键字using namespace组成:
例如: using namespace Jack; //使名称空间Jack中所有的名称都可用
(3) 名称空间示例
//namesp.h
#include<string>
//创造名称空间pers和debts
namespace pers
{
struct Person {
std::string fname;
std::string lname;
};
void getPerson(Person &);
void showPerson(const Person &);
}
namespace debts
{
using namespace pers; //让pers中的名称在debts名称空间可用
struct Debt
{
Person name;
double amount;
};
void getDebt(Debt &);
void showDebt(const Debt &);
double sumDebts(const Debt ar[], int n);
}
//namesp.cpp -- namespaces
#include<iostream>
#include "namesp.h"
namespace pers
{
using std::cout;
using std::cin;
void getPerson(Person &rp) //提供头文件中的函数原型对应的定义
{
cout << "Enter first name: ";
cin >> rp.fname;
cout << "Enter last name: ";
cin >> rp.lname;
}
void showPerson(const Person &rp)
{
cout << rp.lname << ", " << rp.fname;
}
}
namespace debts
{
void getDebt(Debt & rd)
{
getPerson(rd.name);
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;
}
}
//usenmsp.cpp -- using namespace
#include<iostream>
#include"namesp.h"
void other(void);
void another(void);
int main(void)
{
using debts::Debt;
using debts::showDebt;
Debt golf = { {"Benny","Goatsniff"},120.0 };
showDebt(golf);
other();
another();
std::cin.get();
std::cin.get();
return 0;
}
void other(void)
{
using std::cout;
using std::endl;
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;
return;
}
void another(void)
{
using pers::Person;
Person collector = { "Milo","Rightshift" };
pers::showPerson(collector);
std::cout << std::endl;
}