在上一章节中,我们讲解了C++中的模板,模板很大程度上提高了我们编程的效率。这一章节中我们来讲解一下C++中的引用,友元和运算符重载,同样,我们还是会结合汇编语言来讲解,让大家从底层来了解它们到底是什么,能让大家有更好地理解。
一.引用
这里给大家先给出文本定义:
引用是C++引入的新语言特性,他是某一变量的一个别名,使用“&”符号标识。引用的定义格式如下:
数据类型& 引用名 = 变量名; • 1
我们来通过一个简单的程序来看一下:
#include "stdafx.h" int main(int argc, char* argv[]) { int a = 10; int& b = a; printf("%d",a); printf("%d",b); }
我们来到反汇编看一看引用的本质:
int a = 10; C7 45 FC 0A 00 00 00 mov dword ptr [ebp-4],0Ah int& b = a; 8D 45 FC lea eax,[ebp-4] 89 45 F8 mov dword ptr [ebp-8],eax
如果我们单纯的看这个反汇编,我们发现这和指针根本没有区别。
既然它和指针没有区别,那么我们为什么还需要引用?
我们来思考一个问题:我们定义一个指针,如果我们误操作之后,指针指向了它不该指向的地址,那么是不是会引发安全问题?那么引用就很好地解决了这个问题,引用在初始化之后,不能再做修改,即不能用作其他变量的引用。
引用是隐式指针,但引用却不同于指针,使用引用与使用指针有着本质的区别。
注意:
1.引用在定义时必须初始化,且与变量类型保持一致。
2.引用在初始化时不饿能绑定常量值,如int& b = 10;
但是可以通过const int& a = 10;
来使引用绑定常量值。
3.引用在初始化后,其值不能再做修改,即不能用作其他变量的引用。
引用的重要应用
在C++中,引用的一个重要作用是作为函数参数:
#include "stdafx.h" int temp(int& a,int &b){ int c = a; a = b; b = c; } int main(int argc, char* argv[]) { int a = 10; int b = 20; temp(a,b); printf("%d",a); printf("%d",b); }
将引用作为函数参数,可以在函数内部做像指针一样的操作,使用起来又不像指针那样繁琐,这样就克服了值传递和地址传递的缺点。
引用是隐式的指针,但引用又不同于指针,使用引用和使用指针有着本质的区别:
1.指针作为一个变量,需要占据额外的内存单元,而引用指向一个变量,不占据额外的内存单元
2.作为函数参数时,指针的实参是变量的地址,而引用的实参是变量本身,但系统向引用传递的是变量的地址而不是变量的值。
总结
<1>.引用类型是C++类型
<2>.引用只能赋值一次,不能重新辅助
<3>.引用只是变量的一个别名
<4>.引用可以理解为编译器维护的指针,但并不占用空间
<5>.使用引用可以像指针那样去访问,修改对象的内容,这样比指针更安全
二.友元函数
这里先给出友元函数的书面定义,后文中中一句话给大家讲明白:
友元函数可以是类外定义的函数或是其它类中的成员函数,若要在类中声明某一函数为友元函数,则该函数可以操作类中的所有数据。
这里给出一个例子:
class Student{ private: char name; int age; friend xiugai(); } void xiugai(Student a){ }
我们知道C++的封装机制,private成员只有该类的方法才能够访问类中的数据,那么我们在类中定义一个友元函数,就像是告诉这个类:这个函数是你的朋友,它也可以访问你的数据。那么这个函数就可以访问该类的数据,并做修改。
那么友元函数有什么用呢?什么时候需要友元?
当运算符重载的某些场合,需要用到友元。
当两个类需要共享数据的时候,需要用到友元。
友元函数和成员函数有什么区别:
成员函数有this指针,而友元函数没有this指针。
三.运算符重载
我们知道运算符'<' '>' '=' '<=' '>='
等,那么当我们需要用这些运算符来进行我们某些特定场合需要的运算时,这些运算符又不能帮我们完成,有什么办法呢?这里就用到运算符重载了
运算符重载实际上就是函数的替换,我们自己定义好我们需要的运算符需要实现的功能,然后再将它重载为和常见的运算符相同的符号,这样我们在使用这些运算符的时候,就是我们自己定义的操作了。
运算符重载的语法:
返回值类型 operator 运算符名称 (参数列表){ ///函数体 }