C++名称空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字就是针对这种问题而出现的。

一.传统名称空间
  1. 声明区域: 可以在其中进行声明的区域。 例如:可以在函数外面声明全局变量,对于这种变量,其声明区域为其声明所在的文件中。对于在函数中声明的变量,其声明区域为其声明所在的代码块.
  2. 潜在作用域: 变量的潜在作用域从声明点开始,到其声明区域的结尾。 因此潜在作用域比声明区域小,这是由于变量必须定义后才能使用。
  3. 作用域: 变量对程序而言可见的范围被称为作用域
二.新名称空间
通过定义一种新的声明区域来创建命名的名称空间
2.1有两种形式命名空间
有名的命名空间:
       namespace 命名空间名 {
              声明序列可选
       }
匿名的命名空间:
       namespace {
              声明序列可选
       }

eg:利用namespace创建两个名称空间

namespace Jack {
	double pail;            //变量声明
	void fetch();           //函数原型
	int pal;                //变量声明
	struct Well{...};       //结构声明
}

namespace Jill {
	double bucket(double n){...}       //函数定义
	double fetch;                      //变量声明
	int pal;                           //变量声明
	struct Hill{...};                  //结构声明
}

需要有一种方法来访问给定名称空间中的名称。 最简单的方法是,通过作用域解析运算符::,使用名称空间来限定该名称。

Jack::pail = 12.34;              //使用一个变量
Jill::Hill mole;                 //创造一个Hill类型结构
Jack::fetch();                   //使用一个函数

2.2.命名空间可嵌套:

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
}

一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

2.3. 无名命名空间,意味着命名空间中的标识符只能在本文件内访问,相当于给这个标识符加上了static,使得其可以作为内部连接
namespace{
int a =10;
void func(){cout << "hello namespace "<< endl}
}
void test(){
	cout << "a:" << a << endl;
	func();
}
2.4.命名空间是开放的,即可以随时把新的成员加入已有的命名空间中(常用)
namespace A {
    int a = 100;
    int b = 200;
}
//将c添加到已有的命名空间A中
namespace A {
    int c = 300;
}
void test04()
{
    cout<<"A中a = "<<A::a<<endl;//100
    cout<<"A中c = "<<A::c<<endl;//200
}

2.5 命名空间 可以存放 变量 和 函数
namespace A {
    int a=100;//变量

    void func()//函数
    {
        cout<<"func遍历a = "<<a<<endl;
    }
}
void test05()
{
    //变量的使用
    cout<<"A中的a = "<<A::a<<endl;

    //函数的使用
    A::func();
}

三.
  • using声明和using编译指令
      using声明由被限定的名称和它前面的关键字using组成
      using Jill::fetch;
      using编译指令由名称空间名和它前面的关键字using namespace组成(它使名称空间中的所有名称都可用,而不需要使用作用域解析运算符)
      using namespace Jack;

  • 在全局声明区域中使用using编译指令,使该名称空间的名称全局可用
     #include <iostream>
     using namespace std

四.名称空间示例

1.头文件包含:常量,结构定义和函数原型

//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;
	struct Debt   //储存人名和金额
	{
		Person name;
		double amount;
	};
	void getDebt(Debt &);
	void showDebt(const Debt &);
	double sumDebts(const Debt ar[], int n);
}

2.源代码文件,提供头文件中的函数原型对应的定义

//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;
	}
}

3.源代码文件,使用名称空间中声明和定义的结构和函数

//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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值