命名空间
背景
在大型的项目中,通常会出现许多函数,这些函数可能会因为名称或某些原因而相互冲突,使用命名空间可以把不同的函数放在不同的域中,减少程序的维护成本
定义
定义命名空间,需要使⽤namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等
namespace作用为定义出一个独立的域,与其他的全局域隔开,不同的域中可以取相同名称的变量
C++中存在函数局部域、全局域、命名空间域、类域;这些不同的域之中定义的变量并不会相互冲突
namespace只能定义在全局
同时namespace还可以进行嵌套定义:倘若两个人分别负责的函数出现了冲突,只需要把他们的域都归入一个大域下实现嵌套定义,便可以解决问题
项⽬⼯程中多⽂件中定义的同名namespace会认为是⼀个namespace,不会冲突
使用
1.指定命名空间访问(项⽬中推荐这种⽅式)
例如我们要使用cout输出hello world时
#include<iostream>
int main()
{
std::cout << "hello world!" << std::endl;
return 0;
}

2.using将命名空间中某个成员展开(经常访问项⽬中不存在冲突的成员推荐使用)
例如我们需要经常使用cout,同时cout不存在冲突时
#include<iostream>
using std::cout;
int main()
{
cout << "hello world!" << std::endl;
return 0;
}

3.展开命名空间的全部成员(项目中不推荐)
C++标准库都放在std的命名空间中,所以我们在看许多他人的代码时会在起始处看到
using namespace std;
这行代码使用using把命名空间std域展开,此后在使用std的内容时就不需要加上前缀“std::”
同样以上面的例子
#include<iostream>
using namespace std;
int main()
{
cout << "hello world!" << endl;
return 0;
}

但需要注意的是,在大项目中,在全局范围展开std标准库可能会引发一些函数的冲突,需要谨慎使用
输入输出
<iostream>是C++标准的输⼊、输出流库,定义了标准的输入、输出对象
std::cin 是istream类的对象,它主要⾯向窄字符的标准输入流
std::cout 是ostream类的对象,它主要⾯向窄字符的标准输出流
std::endl是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区
<<是流插入运算符,>>是流提取运算符(同时可以用来做位移运算:左/右移)
C++使用cin输入时可以自动查找格式,不需要像C语言一样手动指定输入格式
对于一个int型的a而言,在c语言中需要指定为%d整型
int a;
scanf("%d", &a);
而在C++中只需要
int a;
std::cin >> a;
同样的,在C++中使用cout输出时也会自动选择合适的格式
例如我们想要输出一个int型元素a和a的地址
#include<iostream>
using namespace std;
int main()
{
int a=1;
cout << a << endl;
cout << &a << endl;
return 0;
}

可以看到分别输出了a的值和a的地址
同时C++是兼容C语言的,若是想要输出特定精度的数字,依旧可以采取C语言的输出写法
#include<iostream>
using namespace std;
int main()
{
float a = 1.23456;
printf("%.3f", a);
return 0;
}

缺省函数
缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值(缺省参数也叫默认参数)
在调⽤缺省函数时,如果没有指定实参则采⽤该形参的缺省值,否则使⽤指定的实参
#include<iostream>
using namespace std;
void fun(int a = 0)
{
cout << a << endl;
}
int main()
{
fun();
fun(555);
return 0;
}

可以看到在没有输入实参时,便默认输出了缺省值,有参数时便输出了指定的实参
缺省参数分为全缺省和半缺省参数
全缺省就是全部形参给缺省值
void fun(int a = 0,int b = 0,int c = 0)
{
cout << a << " " << b << " " << c << endl;
}
半缺省就是部分形参给缺省值
void fun(int a,int b = 0,int c = 0)
{
cout << a << " " << b << " " << c << endl;
}
C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值
以下给出错误示范
void fun(int a=0,int b,int c = 0)
{
cout << a << " " << b << " " << c << endl;
}
像这样的函数就是错误的
带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参
函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省 值
void fun(int a = 0, int b, int c = 0);
void fun(int a,int b,int c)
{
cout << a << " " << b << " " << c << endl;
}
函数重载
C++可以在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或类型不同
例子
1.参数类型不同
#include<iostream>
using namespace std;
int fun(int a, int b)
{
cout << "int fun(int a,int b)" << endl;
return a + b;
}
double fun(double a, double b)
{
cout << "double fun(double a, double b)" << endl;
return a + b;
}
int main()
{
cout << fun(1, 2) << endl;
cout << fun(1.5, 5.4) << endl;
return 0;
}

可以看到分别调用了两个不同的函数
2.参数个数不同
#include<iostream>
using namespace std;
void fun()
{
cout << "void fun()" << endl;
}
void fun(int a)
{
cout << "void fun(int a)" << endl;
}
int main()
{
fun();
fun(0);
return 0;
}

可以看到两个调用的函数不一样
3.参数类型顺序不同
#include<iostream>
using namespace std;
void fun(int a,double b)
{
cout << "void fun(int a,double b)" << endl;
}
void fun(double a,int b)
{
cout << "void fun(double a,int b)" << endl;
}
int main()
{
fun(1,1.5);
fun(1.5,1);
return 0;
}

可以看到调用的函数并不相同
错误用例
1.仅返回类型不同
void fun(int a,double b)
{
cout << "void fun(int a,double b)" << endl;
}
double fun(int a, double b)
{
cout << "double fun(int a, double b)" << endl;
return a + b;
}

2.无参函数和全缺省函数
void fun()
{
cout << "void fun()" << endl;
}
void fun(int a = 0)
{
cout << "void fun(int a = 0)" << endl;
}

编译可以通过但是实际调用时会出错,系统不确定该调用哪一个函数
C++函数调使⽤更灵活,而C语⾔是不⽀持同⼀作⽤域中出现同名函数的
引用
定义
引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名
编译器不会为引⽤变量开辟内存空间, 它和它引⽤的变量共用同⼀块内存空间
#include<iostream> using namespace std; int main() { int a = 0; int& b = a; cout << &a << endl; cout << &b << endl; return 0; }
可以看到两者的内存空间是同一块
类型& 引用别名=引用对象;
下面一行便是引用的使用
int a = 0; int& b = a;
特性
引用在定义时必须初始化,以下的代码为错误示范
int a = 0;
int& b;
一个变量可以有多个引用
#include<iostream>
using namespace std;
int main()
{
int a = 0;
int& b = a;
int& c = a;
int& d = a;
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
return 0;
}
可以看到bcd都是a的引用
引用⼀旦引用⼀个实体,再不能引用其他实体
使用
引用在实践中主要是于引用传参和引用做返回值中减少拷贝提⾼效率和改变引用对象时同时改变被 引用对象
#include<iostream>
using namespace std;
void swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
int main()
{
int x = 1, y = 2;
cout << x << " " << y << endl;
swap(x, y);
cout << x << " " << y << endl;
return 0;
}
可以发现通过引用更改了二者实际的值
引用传参相对指针传参更方便⼀些
引用不需要开空间,指针储存变量地址需要开空间
引用使用时必须初始化,指针可以不初始化
引用在初始化引用后就不可以更改引用对象,指针可以更改指向对象
引用可以直接访问对象,指针需要解引用后访问对象
sizeof中二者的大小不同:引用结果为引用类型的大小,指针为地址空间所占大小
指针容易出现空指针和野指针,引用出现几率较低,使用更安全
const引用
const引用的元素变成了只读不可改
一个const元素想被引用只能使用const引用(直接引用会破坏只读不可改的属性,故无法直接引用)
但是一个其他的普通元素可以直接使用const引用
访问权限只能缩小,不能放大
const引用可以引用临时对象,在模板中的作用相当大
内联函数inline
编译时C++编译器会在调用的地⽅展开内联函数,这样调⽤内联函数就不需要建⽴栈帧了,可以提⾼效率
但inline函数的展开与否取决于编译器,编译器会自己根据情况选择展开与否
inline适用于频繁调用的短小函数,包含递归或者内容较多的函数会被编译器忽略
inline函数与C语言的宏函数类似,但使用起来比宏函数方便很多
visual studio的debug版本下默认不使用内联函数
可以看到两者的内存空间是同一块
&spm=1001.2101.3001.5002&articleId=144158152&d=1&t=3&u=56ee6939558440428cb8732725b78080)
258

被折叠的 条评论
为什么被折叠?



