文章目录
萌新的学习笔记,写错了恳请斧正。
C++简介
C++是由 Bjarne Stroustrup 在上世纪80年代开发的一款基于C语音的编程语言。一开始是作为C语言的完善与改进,后来随着一次次标准化更新,已经脱胎换骨了。但是C+依旧向下兼容大部分C语言代码。
这一篇笔记先从一些比较基础的地方讲其与C语言的区别。
C++的关键字(C++98标准)
首先C语言只有32个关键字,而C++98却有63个关键字,C++11及之后的标准中甚至更多。
具体有哪些可以点下面的链接查看:
命名空间
在C语言中,我们能遇到这样的情况:想要用的函数名、变量名在库中已经存在,因此不得不改名。
而在C++中,我们会遇到更多的库,其中有海量的函数,再加上我们自己会写的函数,命名重复的问题就凸显出来。
因此,C++就引入了命名空间的概念,用以对标识符的名称进行本地化,以避免命名冲突或者名字污染。
其原理大致可以理解为把各个函数放到各自的命名空间中,同一个命名空间内还是不能重名,但是不同命名空间之间可以有重名的函数(通过命名空间来区分)。
定义命名空间
定义一个命名空间要使用关键字namespace
,其定义方式与定义结构体类似(也同样可以嵌套):
int rand;
int Add(int Adder1, int Adder2)
{
return Adder1 + Adder2;
}
namespace ExampleSpace1
{
int rand;
int Add(int Adder1, int Adder2)
{
return Adder1 + Adder2;
}
}
namespace ExampleSpace2
{
int rand;
int Add(int Adder1, int Adder2)
{
return Adder1 + Adder2;
}
namespace ExampleSpace3
{
int rand;
int Add(int Adder1, int Adder2)
{
return Adder1 + Adder2;
}
}
}
如上方所示,我们在全局、ExampleSpace1、ExampleSpace2、ExampleSpace2中的ExampleSpace3中分别定义了整型变量rand和函数Add。但是由于其所处命名空间是不同的,所以不会出现问题。
另外,在同一个工程中,可以有多个同名的命名空间,它们最后会被“合并起来”,比方说我们可以在test1.h中定义命名空间Test:
namespace Test
{
int a;
int b;
}
然后在test2.h中继续定义命名空间Test:
namespace Test
{
int c;
int d;
}
那么在之后使用命名空间Test时,两边的内容就相当于“合并”起来作为一个命名空间。
展开(使用)命名空间
那么我们应该如何使用命名空间呢?以下面这段为例:
int a;
namespace ExampleSpace1
{
int a;
int b;
}
namespace ExampleSpace2
{
int c;
namespace ExampleSpace3
{
int d;
}
}
使用命名空间一般有三种方式。
方式:命名空间名称加作用域限定符
两个英文冒号连在一起就是作用域限定符(::)。
int main()
{
printf("%d\n", a); //未加限定时访问全局域的a
printf("%d\n", ::a); //限定为空同样访问全局域的a
printf("%d\n", ExampleSpace1::a); //访问ExampleSpace1中的a
printf("%d\n", ExampleSpace2::a); //访问ExampleSpace2中的a
printf("%d\n", ExampleSpace2::ExampleSpace3::a); //访问ExampleSpace2中的ExampleSpace3中的a
}
方式:用using关键字引入命名空间内容
比方说这样就能引入ExampleSpace1中的b。
using ExampleSpace1::b;
int main()
{
cout << b << endl;
return 0;
}
这里我们不能使用引入ExampleSpace1中的a,因为全局中已经存在一个a了,产生多义性问题。
方式:用using namespace引入整个命名空间
如果某个命名空间里面有大量的内容,我们总不能一个一个去引入,所以我们可以直接引入整个命名空间:
//注意嵌套的情况下不能直接写ExampleSpace3
using namespace ExampleSpace2::ExampleSpace3;
int main()
{
cout << d << endl;
return 0;
}
那如果我们引入ExampleSpace2的话,能不能直接使用ExampleSpace3中的内容呢?
答案是否定的,但是如果引入ExampleSpace2的话我们就可以写成这样了:
using namespace ExampleSpace2;
int main()
{
cout << ExampleSpace3::d << endl;
return 0;
}
此时就不用写成ExampleSpace2::ExampleSpace3::d(虽然也行)。
注意:命名空间展开位置
展开(使用)命名空间是可以在作用域中进行的,不是说一定在全局中展开,比方说:
int main()
{
if (true)
{
using namespace ExampleSpace2::ExampleSpace3;
cout << d << endl;
}
}
注意:展开命名空间的实际含义
比方说全局中的命名空间ExampleSpace1我们如果放在某作用域内展开,并不是说这个时候使用其中的变量或者函数或者别的什么就是该作用域内的东西了。这些东西依旧存在于全局,我们这里的展开只是给了一个权限使得我们能在这个作用域内定向的使用ExampleSpace1中的东西。
这里我们可以看一个例子,比方说下面这段代码的运行结果是10,不会报错:
int a = 0;
int main()
{
if (true)
{
int a = 10;
cout << a << endl<