运算符重载之友元运算符重载
友元可以参考: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)有的运算符不能定义为友元运算符重载函数,如赋值运算符 “=”,下标运算符“[ ]”、函数调用运算符“ () ”等。
运算符重载之友元运算符重载相关推荐
- c 语言友元函数重载,C++友元函数重载++和--运算符
代码: #include #include using namespace std; class one{ public: one(int i); void print(); friend one o ...
- C++——运算符的重载---以成员函数方式重载---以友元函数方式重载
一.运算符的重载 1.运算符的重载 允许把标准运算符(如+ - * /等运算符)应用于自定义数据类型的对象,可以提高程序的可读性,运算符的重载本质上还是函数重载.运算符仅仅是语法上的方便,它是另一种函 ...
- C++运算符重载(友元函数方式)
我们知道,C++中的运算符重载有两种形式:①重载为类的成员函数(见C++运算符重载(成员函数方式)),②重载为类的友元函数. 当重载友元函数时,将没有隐含的参数this指针.这样,对双目运算符,友元函 ...
- 友元函数重载+运算符
#include<iostream> //#include<vector> using namespace std; class Vector {private:int a;i ...
- 【C++】C++类的学习(三)——运算符重载与友元函数
[fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 前言 前面的两篇博文中介绍了类的一些基本特性,今天讲一讲运算符重载和友元. 运算符重载 运算 ...
- C++学习笔记(10)运算符重载,友元函数,友元类
c++允许我们为运算符定义专门的函数,这被称为运算符重载: 运算符可以简化字符串的操作,'+',以及使用关系运算符比较字符串,[ ]运算符访问向量中的元素: 例如: #include <iost ...
- 用成员函数和友元函数重载运算符
一元运算符 首先明白什么是一元,二元和多元运算符,比如++a.b--属于一元运算符,因为参与运算的参数只有一个,以此类推二元运算符就是参与运算的参数有两个,比如a+b. 一元运算符可以表示为:Obje ...
- 【C++的探索路8】运算符重载为友元以及可变长数组程序编写
本篇文章内容首先对运算符重载为友元进行介绍,由于运算符重载这部分内容相对比较多,在结束友元的介绍后,通过一个综合性的小练习对前面的重载部分内容进行一个总结回顾. 运算符重载为友元 由前面关于友元的内容 ...
- c++重载(以运算符重载为主)
重载(OverLoading)是面向对象程序设计多态性的一种体现.所谓重载,是指"同一标识符"在同一作用域的不同场合具有不同的语义,这个标识符可以是函数名或运算符.也就是说,重载可 ...
最新文章
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction 并查集
- 配置apache虚拟host
- 设计模式--桥(Bridge)模式
- Struts的MVC和Spring的MVC的区别
- 数据结构---并查集
- mysql中约束_【MySQL】:MySQL中四大约束
- Spring常用的的注解对应xml配置详解
- java实现加减乘除运算符随机生成十道题并判断对错_2020年Java面试题(3年的工作总结),最全的知识点总结...
- 使用PostgreSQL使用Spring Boot和JPA构建基本应用
- Servlet规范中定义的过滤器
- 谷歌浏览器flash崩溃怎么办 Google Chrome flash崩溃解决方法
- Asp.Net MVC部暑托管服务器iis7提示403错误解决方法
- 专业测试工程师浅谈功能测试用例模板设计
- CSS YUI reset
- 深度森林实现时间序列预测(Python)
- 机器学习中最常见的四种分类模型
- js导出excels表格.XLSX
- LA 4670 Dominating Patterns
- ArrayList线程不安全与Vector线程安全
- ANSYS Workbench 16 - 黄志新(图书阅读总结)
热门文章
- 查看家里WIFI是否被蹭
- Aspose.Cells中文版文档
- java 输出语句 “+“ 号解释
- 太硬核了!这个项目几行代码就把淘宝、拼多多拆解透了
- 引发线程安全的原因是什么?怎么解决?程序员一定要掌握的东西
- win10下配置golang 、beego详细过程
- linux玩游戏咋样,请问用Linux玩游戏的正确姿势?
- 坐而论道,某园子的技术整改及受益者分析
- JXI C# DSP-Core Library 向量文件
- 计算机如何选件组装硬盘,手把手教你如何挑选硬盘,一看就懂