笔记2 · C++命名空间&标准命名空间std

一、引子

一个中大型软件往往由多名程序员共同开发,会使用大量的变量和函数,不可避免地会出现变量名或函数名的命名冲突。当所有人的代码测试通过,结合在一起时就有可能会造成命名冲突。

 例如:小李和小韩都参与了一个文件管理系统的开发,它们都定义了一个全局变量fp,用来指明当前打开的文件,当他们代码结合在一起时。很明显,编译器会提示fp重复定义。

为了解决合作开发的命名冲突的问题,C++引入了命名空间(namespace)的概念。

诸如:

namespace Li//李定义的变量fp
{
    FILE *fp;
}

namespace Wang//王定义的变量fp
{
    FILE *fp;
}

namespace是C++关键字用来定义一个命名空间。语法格式为:

namespace <name>{

     //varibles,functions,classes....

}

二、如何使用

用以下例子说明:

#include <iostream.h>
using namespace std;//这里使我用了全局标准的命名空间

namespace NSA//NSA的命名空间
{
    int a = 10;
}

namespace NSB//NSB的命名空间
{
    int a = 20;
    namespace NSBA//NSB嵌套定义了一个NSBA 表明NSBA域只能为NSB所有
    {
	struct stu//NSBA域里面有一个C++结构体
	{
	    char data[20];
	    int a;
	};
	int a = 1997;//和一个和NSB同名的整形变量a
    }
}

namespace NSC
{
    int a = 827;
}
//如何初始化和使用它们呢?
//如下所示:
main(void)
{
    cout << NSA::a <<endl;
    cout << NSB::a <<endl;
    NSB::NSBA::stu Stu = {"hello world", 1997};
    cout << Stu.data << Stu.a <<endl;
    cout << NSC::a <<endl;

    return 0;
}

编译,运行:

其中  “::”  是一个域解析操作符,在后面学习中会经常看到。除了使用特定人的命名空间外,比如说类体外定义类体中声明的函数也需要用到这个符号。

以上代码是用于测试的,在编译过程中 遇到了警告等问题。我这里特地把#include <iostream> ---新版头文件用旧版头文件#include<iostream.h>来代替,因为现在我们还没接触到标准命名空间std。

解决方法

使用全局的using namespace std; 时, 头文件必须用新版头文件代替。

编译成功了。

除了直接使用域解析操作符意外,还可以采用using关键字声明;例如:

using Li::fp;
fp = fopen("hello.txt", "wb+");
Wang::fp = fopen("world.txt", "r");

 他的意思是using声明后的程序中如果出现了未指明的命名空间就默认使用Li的命名空间;但若是要用小王定义的fp,还是仍然需要使用Wang::fp。

如果命名空间Li中还定义了其他的便来给你,那么同样具有fp变量的同等效果。

命名空间内不仅可以声明或定义变量,对于其他能在命名空间以外声明或定义的名称,同样也能在命名空间内部进行定义,例如:类、函数、typedef、#define等都可以出现在命名空间中。

由命名空间创建的对象也是只能为改命名空间所有者所用。这样,在函数內使用就有了两种方式:

1.usingname space xia;//全局作用域

2.int add(){ using namespace xia; ...}//局部作用域

3.xia::<class name>  <object name>//使用域名解析操作符

C++命名空间比较复杂,我在这里学习的仅仅是冰山一角。后面在学习中我会一步一步的摸索与学习

 

三、C++头文件和标准命名空间std

以上是命名空间的简介,也是使用标准命名空间的基础知识。标准命名空间也是说在后期的C++编码中经常会使用到的代码了:

using namespace std;

早期的C++是在C语言的基础上开发的,早期还不太完善,更不支持命名空间,没有自己的编译器,而是将C++代码翻译成C代码,再通过C编译器完成编译的。

此外吗,C++还开发了一些新的库,增加了自己的头文件,诸如:

iostram.h  用于控制台的输入输出

fstream.h 用于文件操作

complex.h用于复数计算

后来C++引入了命名空间,计划重新将库,类,函数,宏等都纳入一个命名空间中。这个命名空间的名字就是std。---标准命名空间

为了避免重名,C++库对头文件名称也做了调整,去掉了后缀 .h 。所以老式的iostream.h变成了新的iostream。原来C语言中的stdio.h

变成了cstdio; stdlib.h变成了cstdlib。

如何使用:

#include <cstdio>

int main()
{
    std::printf("hello world\n");
    return 0;
}
#include <cstdio>

int main()
{
    printf("hello world\n");
    return 0;
}

这两种方式,在编译器中都能通过,也就是说大部分编译器在实现时没有严格遵循C++标准,程序员可以使用std,也可以不使用std。

只不过,第一种标准的,第二种不标准。

标准命名空间的作用域:

#include <cstdio>
#include <iostream>
#include <string>

int Add(int n)
{
    using namespace std;//作用域Add()
    int sum = 0;
    for(int i=0; i<=n; i++)
    {
	sum += i;
    }
    cout<<"n = "<<n<<" "<<endl; 
    return sum;
}

int main(void)
{
    using namespace std;//作用域main()

    string str = "hello";//定义字符串变量
    int age = 1;

    cout<<"input string:"<<endl;
    cin>>str;
    cout<<"input age:"<<endl;
    cin>>age;

    //std::printf("%s %d\n", str, age);

    cout<<"str is "<<str<<" age is "<<age<<endl;//使用局部标准命名空间

    cout<<"result = "<<Add(age)<<" "<<endl; 

    return 0;
}

一旦使用了标准命名空间,新版支持的标准c库就不能用std::printf()使用了编译器G++不会报错,会报警告 运行时将出现非法指令的错误std::printf("%s %d\n", str, age);

//使用标准命名空间 但是标准写法printf("%s %d\n", str, age);//不使用std 是不标准的写法 但编译器不会报错。

 using namespace std; 它声明了命名空间std,后续如果有未指定的命名空间符号那么默认使用std。诸如:cin、cout都位于命名空间std

四、总结

在很多例子中,std是直接声明在全局的,是为了后面使用函数方便;但是在中大型项目开发中是不被推荐的,这样做增加命名冲突的风险。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值