一、前言
C++是在C语言的基础上容纳进去了面向对象的编程思想以及许多有用的库和编程范式等。那为了补充C语言语法上的不足,C++对C语言进行了一些优化。
二、知识点
1.命名空间
在C/C++中,变量、函数和类都是大量存在的,当这些变量、函数和类的名称存在于全局作用域中时,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,即给它划分区域,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
例如:当我们定义完rand变量并且包含头文件<stdlib.h>时,会发现变量名和头文件里的函数名冲突了,此时会发生错误。
#include <stdio.h>
#include <stdlib.h>//头文件会进行展开
int rand = 0;//命名冲突:自定义名称和库函数名
int main()
{
printf("%d\n", rand);
return 0;
}
(1)命名空间的定义
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字(一般为项目名字),然后接一对{}即可,{}中即为命名空间的成员。(注意:命名空间的定义和类、结构体的定义的区别是:{}后面没有;)
namespace tjl//定义命名空间
{
//命名空间里的成员可定义变量、函数、类型
int rand = 0;
int Add(int a, int b)
{
return a + b;
}
struct A
{
int a;
};
}
2. 命名空间可以嵌套
namespace tjl//命名空间1
{
int Add(int a, int b)
{
return a + b;
}
namespace tyd//命名空间2
{
int Sub(int a, int b)
{
return a - b;
}
}
}
嵌套的命名空间的使用是:
3. 同一个工程中的不同文件允许存在多个相同名称的命名空间,编译器最后会合成在同一个命名空间中。当合并之后还有相同的变量时,我们可以采用嵌套的方式解决。
上面两段代码的命名空间名都是tjl,最终编译器会把它们合成同一个。
注意:定义一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
(2)命名空间的使用
符号::是域作用限定符。当::前面没有限定时,规定访问的是全局的变量。
我们知道,不同作用域的两个变量是可以同名的。那访问顺序是咋样的呢?编译时默认的查找顺序是先局部域再全局域。默认情况下是不会到命名空间里找的。因为命名空间相当于另一个局部域,也就是别人的私有空间。要访问它,必须要经过它的同意。命名冲突的本质是我们不知道去哪里找这个变量,但是有了作用域限定符后,我们清楚了要到哪里去找这个变量,因此不会产生命名冲突了。
那如何去使用命名空间里的成员呢?怎样才是得到了它的同意呢?有三种方式:
- 使用命名空间名称及作用域限定符
#include <stdio.h>
namespace tjl
{
int a = 1;
}
int main()
{
printf("%d\n", tjl::a);//
return 0;
}
- 使用using将命名空间中某个成员引入
#include <stdio.h>
namespace tjl
{
int a = 1;
}
using tjl::a;//
int main()
{
printf("%d\n", a);
return 0;
}
- 使用using namespace 命名空间名称 引入
#include <stdio.h>
namespace tjl
{
int a = 1;
}
using namespace tjl;//展开命名空间,表示可以到这个命名空间里查找变量、函数、类型...
//展开头文件表示在预处理阶段把头文件的内容拷贝过来
int main()
{
printf("%d\n", a);
return 0;
}
有了这三种方式后,命名空间就展开了,我们就可以去这块空间查找变量或函数或类型。
注意:结构体的作用域限定符是放在关键字struct后,的。
2.缺省参数
(1)缺省参数的概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值(也叫默认值)。在调用该函数时,如果没有指定实参则采用该形参的缺省值(默认值),否则使用指定的实参。也就是说,在调用函数时,函数的参数可以省略。
#include <iostream>
int Add(int a = 2, int b = 8)
{
return a + b;
}
int main()
{
Add();//没有传参,使用指定的缺省参数
Add(1, 5);//传参,使用该实参
return 0;
}
(2)缺省参数的分类
- 全缺省参数
void func(int a = 2, int b = 3, int c = 4)//给每个变量都指定默认值
{
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
- 半缺省参数(省部缺分,不是一半)
//给部分参数指定默认值,但必须从右往左依次指定,不可跳跃指定
void func(int a, int b = 3, int c = 4)
{
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
(3)缺省参数的使用
void func(int a = 1 , int b = 3,int c = 4)
{
cout << "a=" << a<<' ';
cout << "b=" << b<<' ';
cout << "c=" << c << endl;
}
int main()
{
func(1,2,3);
func(1,2);
func(1);
func();
func(1, ,2);//错误传参,不能跳跃传,只能依次传
return 0;
}
注意:
1. 半缺省参数必须从右往左依次来给出,不能间隔着给
2. 缺省参数不能在函数声明和定义中同时出现
//a.h
void Func(int a = 10);
// a.cpp
void Func(int a = 20)
{}
// 注意:如果在声明与定义的位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该
//用那个缺省值。所以声明和定义分离时,规定缺省参数在声明给。
3. 缺省值必须是常量或者全局变量
4. C语言不支持(编译器不支持)