c++ (7)- 友元函数-友元类-运算符重载(基础+提高)

1.友元函数

  • 友元函数是一个全局函数
  • 友元函数可以修改类的私有属性,破坏了类的封装性;
  • 友元函数的参数中必然至少会有一个友元类的指针或者引用,用来操作该类的属性;

友元类的关键字friend 的声明位置没有固定的限制,可以声明在友元类的private或者public下;

 

 

  

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class A {
 5 
 6 public :
 7     friend void setData(A *pA, int i);
 8     A(int a) {
 9         this->a = a;
10     }
11     
12     void printA() {
13         cout << "a:" << a << endl;
14     }
15 private:
16     int a;
17 
18 };
19 
20 void setData(A *pA,int i) {
21     pA->a = i;
22 }
23 
24 
25 int main()
26 {
27     //通过友元函数修改类的私有属性
28     A aObject(1);
29     aObject.printA();
30 
31     setData(&aObject,100);
32     aObject.printA();
33 
34     system("pause");
35 
36 
37  }

2.友元类-不重要

2.1  实例

  • B 类是 A 类的友员类,则 B 类的所有成员函数都是 A 类的友员函数
  • 友元类是具有特殊的固定的使用场景的:友员类通常设计为一种对数据操作或类之间传递消息的辅助类
  •  下面的实例中的类的关系:
  1. 【1】A是B的辅助类,其中B类是A类的友元类;
  2. 【2】在B类中包含了A类,A是B的子属性;B类可以通过A类的私有类A成员属性,访问A类的私有属性;
  • 友元类的不常用,友元函数比较常用

 

 

 

 

 2.2 使用友元类的原因

 3.运算符重载

 3.1 运算符重载的引入

【实例】复数的加法运算;

 3.2 运算符重载的语法

 

3.3 例子1

 

 

 

 

3.4 运算符重载的本质:函数的调用;

运算符重载的本质:函数的调用;

3.5 运算符重载的语法

 

 

 

4.二元运算符重载

4.1 语法基础内容

一元运算符重载要比二元运算符重载麻烦

 

 

 4.2 两种方法的函数原型的书写

 

 4.3 友元函数重载

【说明】一般的类的属性都是私有的,否则外部的全局函数无法修改类的私有属性;

因此需要使用“友元函数”的重载。来打破类的属性的私有性。

【特别注意】友元函数的声明和友元函数的全局声明必须一致,否则会发生乱七八糟的错误;

 

 4.4 成员函数重载

 

5.一元运算符重载

 5.1 友元全局函数重载前置++

 

 

 5.2成员函数重载前置--

 

 

 5.3 友元全局函数重载后置++

【说明】后置++是先返回再++,所以要先把值先返回引用或者指针,再累加;

5.3.1 问题:前置++和后置++的函数名字相同会遇到的问题

【说明】此处不属于重载,因为函数的返回值不能作为重载的判断依据;

 【语法】因此为了区分,将后置++的函数定义时候需要使用“int”占位符。

【技巧】因为首先返回值,不能直接“return c1”,否则程序直接结束了;

 先将c1作为临时变量保存下来,在最后返回tmp,不让程序结束;

在返回之前对c1的数据进行处理。

 因为使用到了类的私有属性,所以要声明为该类的友元函数;

 

 5.4 成员函数重载后置--

【技巧】跟之前一样使用到了保存临时变量的技巧

 

 

 5.5 重载的说明

一般的重载都是使用成员函数进行重载

 5.6 重载左移操作符--必须使用友元

 

 

 【特别说明】“左移”“右移”操作符只能使用“友元全局函数”重载实现,因为我们开发人员无法拿到ostream的源码

 

 

 5.7 左操作符函数的返回值(继续上面的5.6 demo)

【说明】因为5.6重载的左操作符的函数的返回值为void;

下面的demo中的140行的代码等价为142行的代码;

即,最后的结果是143行的代码;

最后返回值void无法继续调用函数导致出错;

 【修改之后】修改之后就可以支持链式编程;

    修改后的返回值改为引用;

 

 6.使用友元操作符重载的注意点

7.重载的提高

7.1 重载等号=操作符(对象的拷贝)

【说明】如果类中存在“指针”“引用”等成员变量时,可能会出现“深拷贝”“浅拷贝”;

 

 

 7.2 修改为支持链式操作

 7.3 重载等号操作符的结论

 

posted @ 2021-02-17 15:10  OzTaking  阅读(247)  评论(0)    收藏  举报