从C语言到C++的转变无疑是巨大的:从面向过程编程到面向对象编程……如果一门心思扑到”封装、继承、多态“上学习,恐怕学到后面就会被一些语法整的困惑不解。

本文的目的就是尽量填平C语言与C++之间隐形的坑:C++常用但C语言却没有的基础知识。

本文不仅适合于用做初学C++的入门文章,还可以帮助不清楚C与C++之间差异的读者理清思绪。


一、namespace是什么?

1.情景引入

在C语言编写的代码中,存在着大量的变量、函数。而这些变量、函数又都存储于全局作用域中,这就引出了一个问题:如果变量名与函数名相同的情况下,会导致很多冲突。

如代码:

代码语言:javascript

AI代码解释

#include<iostream>
using namespace std;

int test(int a)
{
	return a;
}
int main()
{
	int test = 1;
	cout << test(test);
	return 0;
}

(cout相当于C语言的printf,cin相当于C语言中的scanf,<<是流插入运算符,>>是流提取运算符,cout/cin不需要像printf/scanf输入输出时那样手动控制格式,C++的输入输出可以自动识别变量类型。

这段代码放在编译器上是编译错误的,原因也很显然:test重定义了。编译器不知道使用的test指的是函数还是变量,这就造成了命名冲突。

C语言没办法解决类似这样的命名冲突问题而C++通过namespace关键字,成功解决了名称冲突的问题。

2.命名空间定义

namespace用法:

命名空间需要用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{} 中即为命名空间的成员。

前面提到C语言将所有的变量、函数都放在全局作用域中,从而造成冲突。

C++允许程序员通过namespace关键字自定义命名空间(作用域),自定义的命名空间同全局作用域一样,也可以以命名空间中可以定义变量/函数/类型。

如:

代码语言:javascript

AI代码解释

namespace a1 
{
    int hello = 6;
	int test(int a)
	{
		return a;
	}
}

那么该如何使用已经定义好的命名空间呢?

3.命名空间的使用

命名空间的使用有三种方式:

①使用某变量/函数前,加空间名称与作用限定符"::".

代码语言:javascript

AI代码解释

int main()
{
	cout << a1::hello;
	return 0;
}

使用某变量/函数前,使用using将命名空间中某个成员引入全局作用域;

代码语言:javascript

AI代码解释

using a1::hello;
int main()
{
	cout << hello;
	return 0;
}

③使用某变量/函数前,使用using namespace “命名空间名”将整个空间引入;

(谨慎使用,防止再次出现冲突问题)

代码语言:javascript

AI代码解释

using namespace a1;
int main()
{
	cout << hello;
	return 0;
}

例如如上述代码通过加入namespace命名空间就能编译通过:

明确告诉编译器,我使用的是a1空间中的函数test,未加作用域限定符的就是全局作用域中的变量test。

代码语言:javascript

AI代码解释

#include<iostream>
using namespace std;

namespace a1 
{
    int hello = 6;
	int test(int a)
	{
		return a;
	}
}

int main()
{
	int test = 1;
	cout << a1::test(test);
	return 0;
}

现在再回过头看“using namespace std”是什么意思就一目了然了。

常见教材上一般直接让初学者直接使用“using namespace std”,却又迟迟不说明原因,其实原因很简单:

<iostream>头文件中包含有cin、cout等标准输入输出的声明,但考虑到命名冲突的问题,于是C++将相关声明都放进了std命名空间中。如果不将std空间通过using展开,那么使用std空间里的成员就需要作用限定符,如std::cout。 实际上std中可以不止有<iostream>头文件中的声明,其他头文件如<vector><string>的声明也可以在其中。

这里还需要指出一个容易误解的区域:很多初学者误以为cin等“函数”的实现是在std中。其实不然:std的主要作用是避免名称冲突,防止标准库的名字(如cout)和你自己写的代码名字(比如你定义一个cout变量)打架。它们的定义是在C++标准库的预编译二进制文件中,std中的声明是为了方便后续的编译链接。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐