1. 命名空间
1.1 域的介绍
域就是指的作用域,分为全局作用域和局部作用域,这一点就不用解释了,先看一个实例来了解域和命名空间的联系
#include <stdio.h> #include <stdlib.h> int rand = 10; int main() { printf("%d\n", rand); return 0; }
上述这段代码会发生报错:rand:重定义,以前的定义是函数(这种情况就是自己定义的和库中定义的重复了,解决方法就是:可以用一个命名空间或者改变量名)
1.2 命名空间的定义
上述例子中说明了域,全局域中有个rand和库中rand()函数命名相同,下面我们来说说命名空间的定义以及域和命名空间的联系
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员(可以是变量、函数、类型)。
namespace ProjectName //一般命名空间命名都是项目名字 { int rand = 10; //变量 int max(int a, int b) //函数 { return a > b ? a : b; } struct node //结构体类型 { int data; struct node* next; }; }
命名空间也是可以嵌套使用的
namespace A { int a = 1; namespace B { int b = 2; } }
同一工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
namespace A { int A = 10; int max(int a, int b) { return a > b ? a : b; } } namespace A { int min(int a, int b) { return a < b ? a : b; } } int main() { int a = 10; int b = 20; printf("%d\n", A::max(a, b)); //::域作用限定符:用来指定命名空间 printf("%d\n", A::min(a, b)); return 0; }
为什么要有命名空间?
C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决.1.自己定义的和库中定义的发生冲突(也就是重复)。2.多人项目中多人定义的发生冲突。
命名空间和域的关系?
一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。但是,不能理解为原本是全局变量外面套层命名空间就把全局变量变为局部变量,并不是这样的,实际上命名空间只是影响了使用,并没有改变生命周期(也就是它是全局变量加上嵌套一层命名空间或者多层它仍然是全局变量,它是局部变量加上嵌套一层命名空间或者多层它仍然是局部变量)
当命名空间名中变量或者函数或者类型发生冲突时,应该怎么办?
这种情况下就是改掉其中一个命名空间名或者改掉其中一个变量或者函数或者类型。
1.3 命名空间的三种使用方式
::这个符号是域作用限定符,用来指定域进行操作。
namespace A { int a = 1; } int main() { printf("%d\n", a); //printf("%d\n",A::a); // 这就是::域作用限定符的作用 return 0; } //bug:“a”: 未声明的标识符
1.指定命名空间访问
namespace name { int num = 1; } int main() { printf("%d\n",name::num); return 0; }
2.全部展开访问
#include <stdio.h> namespace myspace { int rand = 1; void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } } using namespace myspace; //全部展开,不用指定命名空间,直接使用 int main() { printf("%d\n", rand); int a = 10; int b = 20; swap(&a, &b); printf("a=%d,b=%d\n", a, b); return 0; }
3.部分展开
#include <stdio.h> namespace myspace { int rand = 1; void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } } using myspace::rand; //部分展开,直接使用此变量/函数/类型 int main() { printf("%d\n", rand); //部分展开的可以指定可以不指定 int a = 10; int b = 20; myspace::swap(&a, &b); //没有部分展开,只能指定 printf("a=%d,b=%d\n", a, b); return 0; }
实际开发过程中,都要不用到指定或者部分展开,防止发生冲突问题;日常代码量小的时候可以直接用全部展开
2. C++输入&&输出
//先看一眼: #include <iostream> using namespace std; int main() { cout << "hello world" << endl; return 0; }
说明
使用==cout标准输出对象(控制台)和cin标准输入对象(键盘)==时,必须包含< iostream >头文件以及按命名空间使用方法使用std。cout作用就相当于c语言中printf,cin作用就相当于c语言中scanf
out和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在< iostream >头文件。
<<是流插入运算符,>>是流提取运算符。
使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。
C++的输入输
3. 缺省参数
3.1 概念
==缺省参数是声明或定义函数时为函数的参数指定一个缺省值。==在调用该函数时,如果没有指定实
参则采用该形参的缺省值,否则使用指定的实参。
void fun(int a = 100) { printf("fun函数输出:%d\n", a); } int main() { fun(); //输出100 fun(10); //输出10 return 0; }
3.2 缺省参数分类
全缺省参数
void fun(int a = 10, int b = 20, int c = 30) { cout << a + b + c << endl; }
半缺省参数
void fun(int a, int b = 20, int c = 30) { cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; }
注意事项
1.半缺省参数必须从右往左依次来给出,不能间隔着给
2.缺省参数不能在函数声明和定义中同时出现(建议是在声明是给缺省参数,而不是定义给缺省参数)
void fun(int a = 10); void fun(int a = 10){ } //bug:“fun”: 重定义默认参数 : 参数 1
3.使用缺省值,必须从右往左连续使用
void fun(int a = 10, int b = 20, int c = 30) { cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; } int main() { //fun(1, ,3); //err //没有从右向左连续使用 //fun(, , 3); //err //没有从右向左连续使用 fun(1, 2, 3); fun(1, 2); fun(1); fun(); return 0; }
4. 函数重载
4.1 概念
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 参数类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。
1、参数类型不同
int Add(int left, int right) { return left + right; } double Add(double left, double right) { return left + right; }
2、参数个数不同
void f() { cout << "f()" << endl; } void f(int a) { cout << "f(int a)" << endl; }
3、类型顺序不同
void f(int a, char b) { cout << "f(int a,char b)" << endl; } void f(char b, int a) { cout << "f(char b, int a)" << endl; }
4.2 C++支持函数重载的原理–名字修饰
简单的来说就是假如有两个函数,一个是void print(){cout << “print()” << endl;},另外一个是void print(int a){cout << “printf(int a)” << endl;};那么函数名都是相同的,另外满足的是参数个数不同,符合函数重载规定。c语言是不能函数名重定义的,但是c++可以,==那么c++是怎么区分的呢?其实就是编译器把对应的函数名进行修饰,这样拿到其中一个函数时就不会出现重定义现象。==下面通过Linux下观察:
通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修
饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。
如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办
法区分