命名空间
#include<stdio.h> #include<stdlib.h> int rand = 1; int main() { printf("%d\n", rand); return 0; }
在C语言的编译环境下,头文件 #include<stdlib.h>展开之后会包含rand()函数,编译默认的查找成员方式是:先局部,后全局。所以当函数rand()和变量rand同时出现在全局时,程序便会报错
此类情况是不可避免的,尤其是在工程中,命名冲突在所难免,不容小觑。
C++编译系统,为此提供一个解决办法,命名空间
对标识符名称进行本地化,避免命名冲突(名字冲突)
命名空间就类似于在成员与外界之间设置一个围墙,如果想要访问其中的成员,要么通过专属的通道(作用域限定符),要么将围墙进行拆除。
将变量rand放在命名空间namespace M中,按照查找规则,在全局中找到rand()函数;通过域作用限定符,在命名空间中找到变量rand,由此避免了命名冲突
#include<stdio.h> #include<stdlib.h> namespace M { int rand = 1; } int main() { printf("%p\n", rand); //:: 域作用限定符 printf("%d\n", M::rand); return 0; }
命名空间定义
命名空间的定义,需要使用关键字namespace,实例如下
namespace name //name是命名空间的名称 { member //命名空间的成员 }
举例如下
namespace M { int m = 'm'; int n = 'n'; }
与C语言中的结构体类似,命名空间同样也可以嵌套定义
namespace M { member; namespace N { member; } }
举例如下
namespace M { int m = 'm'; int n = 'n'; namespace N { int i = 'i'; int j = 'j'; } }
命名空间定义了新的作用域,命名空间中所有的成员生命周期仅局限于命名空间
命名空间的使用
加命名空间名称及作用域限定符
int main() { printf("%d", M::m); return 0; }
使用using将命名空间中某个成员引入
using作用就类似于打开围墙的专属通道,可以直接访问成员m,但对于成员n的访问还是需要使用作用域限定符
using M::m; int main() { printf("%d\n", m); printf("%d\n", M::n); return 0; }
使用using namespace 命名空间名称引入
using namespace的作用就类似于,直接将围墙进行拆除,可以直接访问所有成员
using namespace M; int main() { printf("%d\n", m); printf("%d\n", n); return 0; }
C++输入,输出
std是C++标准库的命名空间名,C++将标准库的定义实现全部都放在其中
#include<iostream> using namespace std; int main() { cout << "hello crush" << endl; return 0; }
使用cout标准输出对象和cin标准输入对象时,需要包含 <iostream>头文件以及按命名空间使用的方式使用 std
cout和cin时全局的流对象,endl时特殊的C++符号,表示换行输出,类似于C语言中的'\n',全部都包含在<iostream>头文件中
<<是流插入运算符,>>是流提取运算符
C++的输入输出可以自动识别变量类型
举例如下
#include<iostream> using namespace std; int main() { char c = 'c'; int i; //输入变量i的数值 cin >> i; //打印输出变量 i,c cout << i << endl; cout << c << endl; return 0; }
缺省参数
缺省参数概念
缺省参数是声明(定义)函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参
#include<iostream> using namespace std; void test(int i = 1) { cout << i << endl; } int main() { test(0); test(); return 0; }
缺省参数分类
全缺省参数
#include<iostream> using namespace std; void test(int a = 1, int b = 2, int c = 3) { cout << a << " " << b << " " << c << endl; } int main() { test(); return 0; }
半缺省参数(部分缺省)
只能从右往左连续缺省
#include<iostream> using namespace std; void test(int a , int b = 2, int c = 3) { cout << a << " " << b << " " << c << endl; }
注意
半缺省参数必须传递实参,且顺序从左往右,不能间隔赋值
缺省参数不能在函数声明和定义中同时出现,规定只能在声明中存在。因为如果声明和定义中同时存在缺省参数,到底以哪一个作为真正的缺省参数呢?
头文件中声明,源文件中定义。由于同时都存在缺省参数,所以程序会报错
缺省值必须是常量或者全局变量
函数重载
词语具有一词多义的特点,只有通过上下文才能判断该词语的真正的含义,函数重载也是具有类似的特点
函数重载概念
函数重载:函数的一种特殊情况,允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数,类型,类型顺序)不同,常用来处理实现功能类似数据类型不同的问题
形参类型不同
int Add(int left, int right) { cout << "int Add(int left, int right)" << endl; return left + right; } double Add(double left, double right) { cout << "double Add(double left, double right)" << endl; return left + right; }
形参个数不同
void test() { cout << "test()" << endl; } void test(int i) { cout << i << endl; }
参数类型顺序不同
void test(int i, char c) { cout << "void test(int i, char c)" << endl; } void test(char c, int i) { cout << "void test(char c, int i)" << endl; }
还存在一个小问题 函数重载遇上缺省参数
//构成函数重载,同时也是缺省参数 //调用存在歧义,到底该调用哪一个不清楚 void test(int a = 0, int b = 1) { cout << "test(int a,int b)" << endl; } void test() { cout << "test()" << endl; } int main() { test();//二义性 return 0; }