《C++》基础入门_19——命名空间

以下内容为大学期间学习C++语言总结的知识:

《C++》基础入门_01——数据存储,表示形式,基本运算
《C++》基础入门_02——面向对象的总体概括
《C++》基础入门_03——程序的开发过程
《C++》基础入门_04——四大语句
《C++》基础入门_05——函数详解篇
《C++》基础入门_06——面向对象的详述
《C++》基础入门_07——数据的共享保护:const
《C++》基础入门_08——利用数组实现对批量数据的处理
《C++》基础入门_09——指针和引用的讲解
《C++》基础入门_10——用户自定义数据类型详细篇
《C++》基础入门_11——友元的讲解
《C++》基础入门_12——类模板
《C++》基础入门_13——运算符的重载
《C++》基础入门_14——继承与派生
《C++》基础入门_15——多态性
《C++》基础入门_16——输入输出流详讲
《C++》基础入门_17——对象串行化
《C++》基础入门_18——异常处理
《C++》基础入门_19——命名空间
《C++》基础入门_20——文件操作
《C++》基础入门_21——在函数中返回数组的常用方法



在以往的程序中,我们发现都有一句语句:
using namespace std;
此句话就使用了命名空间std。

一、为什么需要命名空间

  • 命名空间是ANSI c++引入的用户命名的作用域,用来处理程序中常见的同名冲突。
  • C语言中引入了3个层次的作用域:
    文件(编译单元)、函数、复合语句
    c++又引入了类作用域,类是出现在文件内的。

下面我们先来分析一下作用域的作用:

  • 若在文件中定义了两个类,这两个类中可以定义同名的函数。引用时,加上类名作为限定即可。

    #include <iostream>
    #include<string>
    using namespace std;
    
    class Student {
    public :
    	void fun1() { cout << "Student::fun1()" << endl; }
    };
    class Teacher {
    	public:
    		void fun1() { cout << "Teacher::fun1()" << endl; }
    		void fun2() { cout << "Teacher::fun2()" << endl; }
    
    };
    
    
    void main() {
    	Student  s;
    	Teacher  t;
    	s.fun1();//Student::fun1()
    	t.fun1();//Teacher::fun1()
    
    }
    
  • 全局变量的作用域是整个程序。若一个程序包含文件A和文件B,在A文件和B文件分别定义了全局变量a,在两文件进行连接时会出现错误,因为有两个同名变量,系统会认为是重复定义的变量。可以通过加某一个文件内对全局变量a加extern,声明一段程序中两个同名变量是同一变量。

  • 一个大型应用软件一般多人开发,若不同的人定义自己的类,放入不同头文件里,在主文件使用这些类时,使用#include指令把这些头文件包含进来。但是不同的头文件有不同的人设计的,很可能发生同名函数或类。程序会发生错误。

head.h文件:

#pragma once
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
	Student(int n,string na) {
		sno = n;
		name = na;
	}
	void getDate();
private:
	int sno;
	string name;
};
void Student::getDate() {
		cout << "Student :" << name << "  " << sno << endl;
}
double fun(double a,double b) {
	return a + b;
}

head1.h文件:

#pragma once
#include <string>
#include<iostream>
using namespace std;
class Student {
public:
	Student(int n,string na) {
		sno = n;
		name = na;
	}
	void getDate();
private:
	int sno;
	string name;
};
void Student::getDate() {
	cout << "name: "<<name << "sno: " << sno << endl;
}
double fun(double a,double b) {
	return a + b;
}

主文件(.cpp):

#include <iostream>
#include "head.h"
#include "head1.h"
#include<string>
using namespace std;
void main() {
	Student stu(1001, "Tom");
	stu.getDate();
	cout << fun(5.7, 5);
}

进行编译:

出错:名字冲突
在这里插入图片描述

  • 不同的库中包含相同实体名,编译时会出现名字冲突,称为:全局命名空间污染。
  • C语言和早期c++未解决此问题。

二、什么是命名空间

为了解决以上问题,ANSI C++增加了命名空间。所谓命名空间,实际上是由程序设计者命名的内存区域。程序设计者根据自己的需求指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分割开。

  • 一个命名空间将不同的标识符集合在一个命名作用域(named scope)内为了解决命名冲突
  • 没有声明命名空间的标识符都处于无名的命名空间中

例如,声明一个命名空间NS:
namespace NS {
class File;
void Fun ();
}
则引用标识符的方式如下,
NS:: File obj;
NS:: Fun ();//被限定名

  1. namespace 是定义命名空间所必须的关键字。
  2. 花括号内是声明快,在其中声明的实体称为命名空间成员。
  3. 使用块内的变量需要加上命名空间名加作用域分辨符::,称为命名空间限定。
  • 声明一个命名空间是的花括号里可以包含的内容:
    1. 变量(可以带初始化)
    2. 常量;
    3. 函数(可以是声明或定义)
    4. 结构体
    5. 模板
    6. 命名空间(嵌套定义)

三、使用命名空间成员的方法

  • 引用的一般形式:
    命名空间名::命名空间成员名
  • c++提供了一些机制,能简化使用命名空间中的成员的手续
    1. 使用命名空间别名
      可以为命名空间起一个别名,用来代替较长的命名空间名。

      namespace Television
      {·····}
      namespace TV=Television;

    2. 使用“using 命名空间成员名”
      using 后面的命名空间成员名必须是由命名空间限定的名字。
      若使用“using 命名空间名”一次只能声明一个命名空间成员,若在一个命名空间中定义了10个实体,就使用10次using命名空间成员名。

      using nsl::Student;

      以上语句声明:在本作用域中会用到命名空间nsl中的成员Student,在本作用域中若使用该命名空间成员时,不必再逐个用命名空间名限定。
      using声明的有效范围是从using开始到using所在的作用域结束。

      using nsl::Student;
      using ns2::Student;
      会产生二义性。

    3. 使用“using namespace 命名空间名”
      一般格式:using namespace 命名空间名;

      using namespace snl;

      声明在本作用域中要用到命名空间nsl的成员,在使用nsl的任何成员时都不需要在使用命名空间限定。
      若同时用using namespace 定义多个命名空间时,易出错。

四、无名的命名空间

前面介绍的都是有名字的命名空间,C++还允许使用没有名字的命名空间。

文件A中:
namespace {
  void fun(){  coout << "jsdj" << endl;  }   fun()函数只在文件A中有效。
}

由于没有名字,在其他文件无法引用,它只在本作用域内有效。
C语言中提供static声明一个函数,其作用是使函数只能作用于本文件。c++保留了static,并通过无名空间实现的。

五、标准命名空间std

  • 标准C++库的所有标识符都是在一个名为std的命名空间中定义的。或者说标准头文件中的函数、类、对象和类模板是在命名空间std中定义的。
  • std是standard的缩写,表示这是存放标准库的有关内容的命名空间。
  • using namespace std;在std中定义的所有标识符在本文件中都可作为全局变量来使用。

六、使用早期的函数库

  • C++从C语言继承了很多函数库,在c++中可以使用C语言的函数库。
  • 若用库中的函数,则需要在程序文件中包含有关的头文件,在不同的头文件中,包含不同的函数声明。
  • c++中使用这些头文件有二种方法:
    1. 用C语言程序中使用的传统老方法。头文件后缀包含.h.
      c语言中无命名空间,在c++中若用带.h的头文件,不需要使用命名空间。

      例如:#include <math.h>

    2. 用c++新方法。c++标准规定头文件不含后缀.h。
      为了表示与c的头文件有联系又有区别。c++的头文件名在C语言相应的头文件(不含.h)之前加字母c。
      需要使用命名空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值