友元可以参考:https://blog.csdn.net/aaqian1/article/details/84427884

友元运算符重载函数: 把运算符重载函数定义为某个类的友元函数。

1、定义友元运算符重载函数的语法形式

(1)在类的内部,定义友元运算符重载函数的格式如下:

friend 函数类型 operator 运算符(形参表)
{函数体
}

(2)友元运算符重载函数也可以在类中声明友元函数的原型,在类外定义。
在类中,声明友元运算符重载函数原型的格式:

class X{friend 函数类型 operator 运算符(形参表);
}

在类外,定义友元运算符重载函数的格式如下:

函数类型 operator 运算符(形参表){函数体
}

由于友元运算符重载函数不是该类的成员函数,所以在类外定义时不需要缀上类名。
若友元运算符重载函数重载的是双目运算符,则参数表中有两个操作数;若重载的是单目运算符,则参数表中只有一个操作数。

2、双目运算符重载

例 1:用友元运算符重载函数进行复数运算。

两个复数 a+bi 和 c+di 进行加、减、乘、除的方法如下:
加法:(a+bi)+(c+di)=(a+b)+(c+d)i
减法:(a+bi)-(c+di)=(a-b)+(c-d)i
乘法:(a+bi) * (c+di)=(ac-bd)+(ad+bc)i
除法:(a+bi) / (c+di)=(a+bi) * (c-di) / (cc+dd)
  在 C++ 中,不能直接进行复数的加、减、乘、除运算,不过可以定义四个友元运算符重载函数,通过重载“+、-、*、/ ”运算符来实现复数运算。
代码如下:

#include<iostream>
using namespace std;
class Complex{private:double real;    //复数实部 double imag;   //复数虚部 public:Complex(double r=0.0,double i=0.0); //https://blog.csdn.net/aaqian1/article/details/83894795。带默认参数的构造函数 void print();friend Complex operator+(Complex& a,Complex& b);  //声明运算符,重载函数friend Complex operator-(Complex& a,Complex& b); //声明运算符,重载函数friend Complex operator*(Complex& a,Complex& b); //声明运算符,重载函数friend Complex operator/(Complex& a,Complex& b); //声明运算符,重载函数
};
Complex::Complex(double r,double i){    //构造函数 real=r;imag=i;
}
Complex operator+(Complex& a,Complex& b){Complex temp;temp.real=a.real+b.real;temp.imag=a.imag+b.imag;return temp;
}
Complex operator-(Complex& a,Complex& b){Complex temp;temp.real=a.real-b.real;temp.imag=a.imag-b.imag;return temp;
}
Complex operator*(Complex& a,Complex& b){Complex temp;temp.real=a.real*b.real-a.imag*b.imag;temp.imag=a.real*b.imag+a.imag*b.real;return temp;
}
Complex operator/(Complex& a,Complex& b){Complex temp;double t;t=1/(b.real*b.real+a.imag*b.imag);temp.real=(a.real*b.real+a.imag*b.imag)*t;temp.imag=(b.real*a.imag-a.real*b.imag)*t;return temp;
}
void Complex::print(){  //显示输出复数 cout<<real;if(imag>0)cout<<"+";if(imag!=0)cout<<imag<<'i'<<endl;
}
int main(){Complex A1(2.3,1),A2(3.6,2.8),A3,A4,A5,A6;A3=A1+A2;A4=A1-A2;A5=A1*A2;A6=A1/A2;A3.print();A4.print();A5.print();A6.print();return 0;
}

执行结果如下:

  一般而言,如果在类 X 中采用友元函数重载双目运算符 @ ,而 aa 和 bb 是类 X 的两个对象,则以下两种函数调用方法是等价的:

aa@bb;      //隐式调用
operator@(aa,bb);      //显示调用

说明:
(1)有时,在函数返回的时候,可直接用类的构造函数来生成一个临时对象,而不对该对象进行命名,如可将例 1 中的重载运算符“ + ”的友元运算符重载函数

Complex operator+(Complex& a,Complex& b){Complex temp;temp.real=a.real+b.real;temp.imag=a.imag+b.imag;return temp;
}

改为:

Complex operator+(Complex& a,Complex& b){return Complex(a.real+b.real,a.imag+b.imag);
}

其中 return 语句中的

Complex(a.real+b.real,a.imag+b.imag);

是建立的一个临时对象,它没有对象名,是一个无名对象。在建立临时对象过程中调用构造函数。return 语句将此临时对象作为函数返回值。
这种方法的执行的效率比较高,但是前一种方法的可读性比较好。
(2)有的 C++ 系统(如 Visual C++ 6.0)没有完全实现 C++ 标准,它所提供的不带后缀的“ .h ”的头文件不支持友元运算符重载函数,在 Visual C++ 6.0 中编译会出错,这时可采用带后缀的“ .h ”头文件。将程序中的

#include<iostream>
using namespace std;

改为

#include<iostream.h>

即可顺利运行。

3、单目运算符重载

  单目运算符只有一个操作数,如 -a、&b、!c、++p等。

例 2:用友元函数重载单目运算符“-”

#include<iostream>
using namespace std;
class Coord{private:int x,y;public:Coord(int x1=0,int y1=0){x=x1;y=y1;}friend Coord operator-(Coord &obj);  //声明为单目运算符 "-" 重载函数void print();
};
Coord operator-(Coord &obj){    //定义单目运算符 "-" 重载函数obj.x=-obj.x;obj.y=-obj.y;return obj;
}
void Coord::print(){cout<<"x="<<x<<"y="<<y<<endl;
}
int main(){Coord ob1(50,60),ob2;ob1.print();ob2=-ob1;ob2.print();return 0;
}

输出结果:

例 3:用友元函数重载单目运算符“++”

#include<iostream>
using namespace std;
class Coord{private:int x,y;public:Coord(int x1=0,int y1=0){x=x1;y=y1;}friend Coord operator++(Coord &obj);   //声明为单目运算符 "-" 重载函数void print();
};
Coord operator++(Coord &obj){ //定义单目运算符 "-" 重载函数++obj.x;++obj.y;return obj;
}
void Coord::print(){cout<<"x="<<x<<";y="<<y<<endl;
}
int main(){Coord ob1(50,60);ob1.print();++ob1;ob1.print();operator++(ob1);ob1.print();return 0;
}


如果将友元运算符重载函数定义为以下格式:

friend Coord operator++(Coord op){ ++obj.x;++obj.y;return obj;
}


  这个运行结果是错误的,原因是这个函数的形参是对象,是通过传值的方法传递参数的,函数体内对形参 obj 的所有修改都无法传到函数体外。即,实际上 operator++ 函数中 obj.x 和 obj.y 的增加并没有引起实参 ob1.x 和 ob1.y 的增加,因此造成了运行结果的错误。
  而形参是对象的引用时,是通过传址的方式传递参数的,函数形参 obj.x 和 obj.y 的改变将引起实参 ob1 的变化。

  一般而言,如果在类 X 中采用友元函数重载单目运算符 @ ,而 aa 是类 X 的两个对象,则以下两种函数调用方法是等价的:

@aa;    //隐式调用
operator@(aa);     //显式调用

说明:
(1)运算符重载函数 operator@ 可以返回任何类型,甚至可以是 void 类型,但通常返回的类型与它操作的类的类型相同,这样可以使重载运算符用在复杂的表达式中。
(2)有的运算符不能定义为友元运算符重载函数,如赋值运算符 “=”,下标运算符“[ ]”、函数调用运算符“ () ”等。

运算符重载之友元运算符重载相关推荐

  1. c 语言友元函数重载,C++友元函数重载++和--运算符

    代码: #include #include using namespace std; class one{ public: one(int i); void print(); friend one o ...

  2. C++——运算符的重载---以成员函数方式重载---以友元函数方式重载

    一.运算符的重载 1.运算符的重载 允许把标准运算符(如+ - * /等运算符)应用于自定义数据类型的对象,可以提高程序的可读性,运算符的重载本质上还是函数重载.运算符仅仅是语法上的方便,它是另一种函 ...

  3. C++运算符重载(友元函数方式)

    我们知道,C++中的运算符重载有两种形式:①重载为类的成员函数(见C++运算符重载(成员函数方式)),②重载为类的友元函数. 当重载友元函数时,将没有隐含的参数this指针.这样,对双目运算符,友元函 ...

  4. 友元函数重载+运算符

    #include<iostream> //#include<vector> using namespace std; class Vector {private:int a;i ...

  5. 【C++】C++类的学习(三)——运算符重载与友元函数

    [fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 前言 前面的两篇博文中介绍了类的一些基本特性,今天讲一讲运算符重载和友元. 运算符重载 运算 ...

  6. C++学习笔记(10)运算符重载,友元函数,友元类

    c++允许我们为运算符定义专门的函数,这被称为运算符重载: 运算符可以简化字符串的操作,'+',以及使用关系运算符比较字符串,[ ]运算符访问向量中的元素: 例如: #include <iost ...

  7. 用成员函数和友元函数重载运算符

    一元运算符 首先明白什么是一元,二元和多元运算符,比如++a.b--属于一元运算符,因为参与运算的参数只有一个,以此类推二元运算符就是参与运算的参数有两个,比如a+b. 一元运算符可以表示为:Obje ...

  8. 【C++的探索路8】运算符重载为友元以及可变长数组程序编写

    本篇文章内容首先对运算符重载为友元进行介绍,由于运算符重载这部分内容相对比较多,在结束友元的介绍后,通过一个综合性的小练习对前面的重载部分内容进行一个总结回顾. 运算符重载为友元 由前面关于友元的内容 ...

  9. c++重载(以运算符重载为主)

    重载(OverLoading)是面向对象程序设计多态性的一种体现.所谓重载,是指"同一标识符"在同一作用域的不同场合具有不同的语义,这个标识符可以是函数名或运算符.也就是说,重载可 ...

最新文章

  1. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction 并查集
  2. 配置apache虚拟host
  3. 设计模式--桥(Bridge)模式
  4. Struts的MVC和Spring的MVC的区别
  5. 数据结构---并查集
  6. mysql中约束_【MySQL】:MySQL中四大约束
  7. Spring常用的的注解对应xml配置详解
  8. java实现加减乘除运算符随机生成十道题并判断对错_2020年Java面试题(3年的工作总结),最全的知识点总结...
  9. 使用PostgreSQL使用Spring Boot和JPA构建基本应用
  10. Servlet规范中定义的过滤器
  11. 谷歌浏览器flash崩溃怎么办 Google Chrome flash崩溃解决方法
  12. Asp.Net MVC部暑托管服务器iis7提示403错误解决方法
  13. 专业测试工程师浅谈功能测试用例模板设计
  14. CSS YUI reset
  15. 深度森林实现时间序列预测(Python)
  16. 机器学习中最常见的四种分类模型
  17. js导出excels表格.XLSX
  18. LA 4670 Dominating Patterns
  19. ArrayList线程不安全与Vector线程安全
  20. ANSYS Workbench 16 - 黄志新(图书阅读总结)

热门文章

  1. 查看家里WIFI是否被蹭
  2. Aspose.Cells中文版文档
  3. java 输出语句 “+“ 号解释
  4. 太硬核了!这个项目几行代码就把淘宝、拼多多拆解透了
  5. 引发线程安全的原因是什么?怎么解决?程序员一定要掌握的东西
  6. win10下配置golang 、beego详细过程
  7. linux玩游戏咋样,请问用Linux玩游戏的正确姿势?
  8. 坐而论道,某园子的技术整改及受益者分析
  9. JXI C# DSP-Core Library 向量文件
  10. 计算机如何选件组装硬盘,手把手教你如何挑选硬盘,一看就懂