【C++】命名空间、缺省参数、函数重载、引用

05-14 1117阅读

文章目录

  • 1.认识命名空间
  • 2.命名空间的使用
  • 3.C++的输入和输出
  • 4.缺省参数
    • 4.1缺省参数的概念
    • 4.2缺省参数的分类
    • 5.函数重载
    • 6.引用
      • 6.1引用的概念
      • 6.2引用的特性
      • 6.3常引用(重点题目)
      • 6.4引用和指针的区别

        1.认识命名空间

        C++总计63个关键字,C语言32个关键字【C++】命名空间、缺省参数、函数重载、引用

        下面让我们学习一下第一个关键字namespace

        首先,我们来看下面的代码

        【C++】命名空间、缺省参数、函数重载、引用

        我们定义了一个名为 rand 的全局变量,此时可以正确的打印出来。

        当我们引用了这个头文件时,我们发现此时代码就会报错,如下图。

        【C++】命名空间、缺省参数、函数重载、引用

        【C++】命名空间、缺省参数、函数重载、引用

        我们都知道,rand是一个产生随机数的函数名,此时该名称与我们定义的全局变量命名发生了冲突,编译器就不知道选哪个了。

        然而,C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决

        使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

        定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。

        命名空间有几种使用方式:

        1. 正常的命名空间定义
        //aim 是命名空间的名字,实际中一般以项目名称命名
        namespace aim1
        {
        	int rand = 10;
        }
        
        1. 嵌套定义
        namespace aim1 //命名空间1
        {
        	int rand = 10;
        	namespace aim2//命名空间2
        	{
        		int rand = 20;
        	}
        }
        
        1. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中

        两个文件中的同名命名空间最后会进行合并,因此会出现重定义问题。

        【C++】命名空间、缺省参数、函数重载、引用

        注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

        2.命名空间的使用

        使用命名空间解决访问冲突的问题后,我们发现仍然访问不到它,此时rand使用的依然是rand函数,打印出来函数的地址。

        【C++】命名空间、缺省参数、函数重载、引用

        下面就来介绍一下命名空间是如何访问的,有3种方式:

        1. 加命名空间名称及作用域限定符

        作用域限制符就是两个冒号,此时我们就可以访问到定义的变量了

        【C++】命名空间、缺省参数、函数重载、引用

        1. 使用using将命名空间中某个成员引入

        using是我们学习的第二个关键字

        【C++】命名空间、缺省参数、函数重载、引用

        我们发现,只有被引入的成员才可以被访问,其它成员依旧不可以。若想访问其它成员,也需要将其引入

        1. 使用using namespace 命名空间名称引入

        【C++】命名空间、缺省参数、函数重载、引用

        此时我们发现,a变量可以访问了,然而rand又出现了问题。什么原因呢?

        我们知道,编译器的默认查找是:

        a. 当前局部域

        b. 全局域

        b. 到展开的命名空间中查找

        此时我们的全局域中和命名空间中都有rand,显然不知道选哪一个,此时我们就需要指定了。因此使用第三种方式时要慎重,不然就是自找麻烦

        【C++】命名空间、缺省参数、函数重载、引用

        此时我们就可以发现,若某一成员需要经常使用,可以将其引入;对于不常使用的成员,可以使用命名空间加作用域限定符。

        【C++】命名空间、缺省参数、函数重载、引用

        很显然,引入了成员后使用更加方便。

        自己在学习中遇到的问题:为什么使用命名空间中的宏时不需要指定?

        【C++】命名空间、缺省参数、函数重载、引用

        宏定义是在编译时预处理阶段完成的,而命名空间是在编译时进行名称空间分配和解析的。在预处理阶段,编译器并不知道命名空间的存在,所以它无法对命名空间进行解析,因此也就无法指定命名空间。

        当使用命名空间内的宏时,编译器会在预处理阶段将宏展开成相应的代码,而展开后的代码中不包含命名空间,因此不需要指定命名空间。

        3.C++的输入和输出

        • 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含头文件以及按命名空间使用方法使用std

          【C++】命名空间、缺省参数、函数重载、引用

          • cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含头文件中。
          • 是流提取运算符。
          • 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型

            浮点数输出时,也不会像scanf 那样默认小数点后6位;它是原样输出。

            【C++】命名空间、缺省参数、函数重载、引用

            • 输入时,也不需要取地址了

              【C++】命名空间、缺省参数、函数重载、引用

              std命名空间的使用惯例:

              std是C++标准库的命名空间,如何展开std使用更合理呢?

              1. 在日常练习中,建议直接using namespace std即可,这样就很方便。
              2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以在项目开发中建议使用像 std::cout这样使用时指定命名空间 或 using std::cout展开常用的库对象/类型等方式。

              4.缺省参数

              4.1缺省参数的概念

              缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

              【C++】命名空间、缺省参数、函数重载、引用

              4.2缺省参数的分类

              1. 全缺省参数

              【C++】命名空间、缺省参数、函数重载、引用

              2. 半缺省参数

              【C++】命名空间、缺省参数、函数重载、引用

              注意:

              • 半缺省参数必须从右往左依次来给出,不能间隔着给。

                【C++】命名空间、缺省参数、函数重载、引用

                • 缺省参数不能在函数声明和定义中同时出现

                  如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值

                  【C++】命名空间、缺省参数、函数重载、引用

                  【C++】命名空间、缺省参数、函数重载、引用

                  • 缺省值必须是常量或者全局变量

                    5.函数重载

                    C语言是不支持同名函数存在的,C++支持。

                    函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数的个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

                    1. 参数类型不同

                    【C++】命名空间、缺省参数、函数重载、引用

                    1. 参数类型的顺序不同

                    【C++】命名空间、缺省参数、函数重载、引用

                    1. 参数的个数不同

                    【C++】命名空间、缺省参数、函数重载、引用

                    注意:

                    • 同一作用域中,同名函数要想同时存在,必须满足重载的规则。
                    • 不同作用域,可以有同名函数
                    • 返回值是不构成重载的(返回值不像参数,编译器对它是无法区分的,它也不是必须的)
                    • 重载的规则是针对于参数的类型和个数,与参数的名称无关、参数缺省无关

                      为什么C++支持重载,C语言不支持?

                      • 因为在程序进行链接的时候,是使用函数名去找地址的,如果声明和定义分离,C语言是直接使用函数名去找,区分不开。
                      • C++使用函数名修饰规则,可以区分。

                        6.引用

                        6.1引用的概念

                        引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间,它们的地址是一样的。

                        定义方式:类型& 引用变量名(对象名) = 引用实体;

                        【C++】命名空间、缺省参数、函数重载、引用

                        注意:引用类型必须和引用实体是同种类型的

                        【C++】命名空间、缺省参数、函数重载、引用

                        引用就是祖师爷本贾尼觉得C语言指针不好才搞得,下面的代码就比指针方便的多。

                        【C++】命名空间、缺省参数、函数重载、引用

                        6.2引用的特性

                        1. 引用在定义时必须初始化
                        2. 一个变量可以有多个引用
                        3. 引用一旦引用一个实体,再不能引用其他实体
                        1. 引用在定义时必须初始化

                        【C++】命名空间、缺省参数、函数重载、引用

                        1. 一个变量可以有多个引用
                        int main()
                        {
                        	int x = 10;
                        	//一个变量多个引用
                        	int& a = x;
                        	int& b = x;
                        	int& c = x;
                        	int& d = x;
                        	return 0;
                        }
                        
                        1. 引用一旦引用一个实体,再不能引用其他实体

                        下面的代码中是将a变成y的别名?还是将y赋值给a呢?

                        【C++】命名空间、缺省参数、函数重载、引用

                        很显然,它是将y赋值给了a

                        6.3常引用(重点题目)

                        void TestConstRef()
                        {
                        	const int a = 10;
                        	//int& ra = a;   // 该语句编译时会出错,a为常量
                        	const int& ra = a;
                        	// int& b = 10;  // 该语句编译时会出错,b为常量
                        	const int& b = 10;
                        	double d = 12.34;
                        	//int& rd = d;  // 该语句编译时会出错,类型不同,d为常量
                        	const int& rd = d;
                        }
                        
                        1. 权限的平移
                        int main()
                        {
                        	const int m = 0;
                        	//权限的放大
                        	//int& n = m; //error  m的权限是可读,n的权限是可读可写的
                        	//权限的平移
                        	const int& n = m;//可以
                        	
                        	//可以,不是权限的放大
                        	//只是将m的值拷贝给x,x的修改不影响p
                        	int x = m;
                        	return 0;
                        }
                        
                        1. 权限的缩小

                        【C++】命名空间、缺省参数、函数重载、引用

                        1. 权限的放大(错误、易错)
                        int main()
                        {
                        	const int m = 0;
                        	//cosnt修饰指针,左定值,右定向
                        	//p1可以修改,*p1不可以,const修饰的是*p1
                        	const int* p1 = &m;
                        	p1++;
                        	//权限的放大,不可以
                        	//int* p2 = p1;  //易错
                        	//权限平移,可以
                        	const int* p2 = p1;
                        	return 0;
                        }
                        

                        总结:值之间没有权限的放大和缩小的概念,只是一个拷贝;指针与引用有权限放大与缩小的概念,权限只可以缩小,不可以放大

                        6.4引用和指针的区别

                        在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。

                        【C++】命名空间、缺省参数、函数重载、引用

                        在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

                        int main()
                        {
                        	int x = 0;
                        	int& y = x;
                        	y = 10;
                        	
                        	int n = 10;
                        	int* p = &n;
                        	*p = 20;
                        	return 0;
                        }
                        

                        我们来看引用和指针的反汇编对比

                        【C++】命名空间、缺省参数、函数重载、引用

                        引用和指针的不同

                        1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
                        2. 引用在定义时必须初始化,指针没有要求
                        3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
                        4. 没有NULL引用,但有NULL指针
                        5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
                        6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
                        7. 有多级指针,但是没有多级引用
                        8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
                        9. 引用比指针使用起来相对更安全
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]