C++ 引用,友元,运算符重载

简介: C++ 引用,友元,运算符重载

在上一章节中,我们讲解了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 运算符名称 (参数列表){
///函数体
}




相关文章
|
8天前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
51 6
|
5月前
|
存储 编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(一)
【C++】深入探索类和对象:初始化列表及其static成员与友元
124 2
|
4月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
169 5
|
5月前
|
C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(二)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
5月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
57 1
|
5月前
|
编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(三)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
5月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
53 0
|
6月前
|
C++
C++(十五) 运算符重载
C++中的运算符重载允许对已有运算符的功能进行重新定义,从而扩展语言功能、简化代码并提升效率。重载遵循特定语法,如 `friend 类名 operator 运算符(参数)`。重载时需注意不可新增或改变运算符数量、语义、优先级、结合性和返回类型。常见示例包括双目运算符 `+=` 和单目运算符 `-` 及 `++`。输入输出流运算符 `&lt;&lt;` 和 `&gt;&gt;` 也可重载。部分运算符只能作为成员函数重载。
|
6月前
|
编译器 数据安全/隐私保护 C++
C++(十四) friend友元
友元机制允许非成员函数或类访问私有成员,提高程序效率,但会破坏封装性。友元可以是函数或类,并以关键字`friend`声明。友元函数不是成员函数,需通过对象访问私有成员。友元类使所有成员函数可访问另一个类的私有成员,常用于简化开发。友元声明位置灵活,但不影响访问控制。使用友元需注意其单向性和非传递性。
|
8月前
|
存储 安全 C++
浅析C++的指针与引用
虽然指针和引用在C++中都用于间接数据访问,但它们各自拥有独特的特性和应用场景。选择使用指针还是引用,主要取决于程序的具体需求,如是否需要动态内存管理,是否希望变量可以重新指向其他对象等。理解这二者的区别,将有助于开发高效、安全的C++程序。
54 3