C++命名空间详解

             在C++中,我们经常会用到 using namespace std 这一句代码,大家知道这句代码是什么含义吗?对,是使用std这个命名空间。命名空间(namespace)是C++用来避免命名冲突的机制。命令空间相当于一个作用域,在这个作用域中,所有的表示符都是唯一的。不同命名空间的名字作用域也不同,这样就保证不同命名空间相互不影响,即便在两个命名空间的表识符是相同的,也不会产生冲突。这句话怎么理解呢?

       大家都知道在编程中如果在一个函数中定义两个名字相同的变量,便会报重定义错误。命名空间就是为解决这一类问题解决的。举一个例子,假如没有命名空间,我们现在一般用C++标准库命名空间里的cout方法进行输出调试。但假如其它厂商提供的库中也有cout方法,而且它的作用和标准库中的不一样,我们现在编程两个都要用。重复了,怎么办?有了命名空间就不一样了,我们现在就用自定义的命名空间进行测试一下。

       先说一下,如何自定义命名空间,

        namespace  myspace{

        //变量声明

//函数声明

//类型定义

}

来一个实例,在math2.h文件中定义如下:

#pragma once
namespace math {
int x;
const double C = 3 * pow(10, 6);
double add(double a, double b) {
return a + b;
}
}

namespace math2 {
double add(double a, double b) {
return (a + b) < 0 ? abs(a + b): a + b;
}
}


   我在math.h文件中定义了两个命名空间,math和math2,两个命名空间都有一个add函数,我在main.cpp这样做,

#include "stdafx.h"
#include<iostream>
#include"math2.h"

int main()
{
int a = -10, b = -20;
cout << "in math;a+b=" <<math:: add(a, b) << endl;
cout << "in math2:a+b=" << math2::add(a, b) << endl;
    return 0;
}


可以看到,我们在两个命名空间中定义了两个相同名字的函数,但我们却能调到想调的函数,在这里我们不能使用using namespace math和using namespace math2。因为不这样使用math:: add(a, b),编译器还是不知道调用哪个。c++标准库遇到使用相同方法的时候也是直接在方法前面加命名空间。

 

      还有一个问题,那就是std这个命名空间包含了整个C++标准库,而库又是经常更新升级的,难道他们这个命名空间每更新一次就要改一遍?其实不是的,命名空间也是可以扩展的,如果你在不同文件中定义相同的命名空间,就会被认为是相同的编译空间,一个定义是对命名空间的扩展,但你必须保证你这一个命名空间里面的成员不重复。

下面我对math命名空间进行扩展,我在math3.h文件中定义如下:

#pragma once
namespace math {
double substract(double a, double b) {
return a - b;
}
double multi(double a, double b) {
return a*b;
}
};


在main.cpp中的定义:

#include "stdafx.h"
#include<iostream>
#include"math2.h"

#include"math3.h"
using namespace math;


int main()
{
int a = -10, b = -20;
cout << "in math;a+b=" <<math:: add(a, b) << endl;
cout << "in math:a-b=" << math::substract(a, b) << endl;
    return 0;
}


可以发现他们是属于同一个命名空间的,因为只用了一个using namespace math。


         使用命名空间的时候也可以缩小作用域,例如只使用cout这个函数就可以在直接使用using std::cout;就行,这样下面的语句cout前面就不需要加std::,但其他的如endl就还需要。而using namespace std;则是声明了整个命名空间,作用覆盖了全部。

        命名空间还可以取多个别名,比如为std取个别名,namespace C++Library=std;这样赋值之后,C++Library就代表这个别名,自己创建的命名空间也可以取别名。


     编程我发现main函数所在文件中的头文件的顺序不同事会产生一些变化,比如<iostream>头文件的下几层中,包含了<cmath>和其它几个头文件,有趣的是,如果你的头文件放在<iostream>之后,那你这个头文件张用到的<cmath>中的函数时,将不再需要#include <cmath>,这是因为预编译的时候,先编译了<iostream>进而编译了<cmath>文件,所以再编译自己头文件时,已经存在<cmath>的编译文件。




猜你喜欢

转载自blog.csdn.net/huangyilinnuli/article/details/78504034
今日推荐