热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Ⅴ运算符重载

1.从函数重载到运算符重载1.1多态性?使用一致的接口(uniforminterface)处理不同类型的数据?例子:运算符重载(+)3.14+0.00153.1415[1,2,3]

1. 从函数重载到运算符重载

1.1 多态性

? 使用一致的接口(uniform interface)处理不同类型的数据

?例子:运算符重载(+

3.14 + 0.0015 = 3.1415

[1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]

[3+4i] + [1+5i] = [4+9i]

"coffee" + " tea" = "coffee tea"


1.2 函数重载

一个名字,却可以有好几个函数,根据参数的个数和种类区分


1.3 运算符重载

一个运算符,保留功能,对象可能不同


1.4 复数类(Complex)的实现:(a+bi)+(c+di) = (a+c) + (b+d)i


#include
using namespace std;
class Complex
{
float real, imag; //实部和虚部
public:
Complex(
float r=0,float i=0)
{
real
= r;
imag
= i;
}
Complex
operator+(Complex other) //+运算符的重载
{
Complex r;
r.real
= real + other.real;
r.imag
= imag + other.imag;
return r;
}
void Output()
{
if(imag>0)
cout
<"+" <"i" << endl;
else
cout
<"i" << endl;
}
};
int main()
{
Complex a(
2,3), b(3, 4), c;
c
= a + b;
c.Output();
return 0;
}


2.运算符重载规则

2.1 入选

?可重载

技术分享图片

 

 

 

?不可重载

①.    ② .*   ③::     ④?:

 


2.2 重载规则

? 重载后运算符的优先级和结合性不变

? 运算符操作数的个数不能改变

? 不能重载C++中不支持的运算符 (@、#、$等,emmmm,拒绝创新喽)

? 保持运算符的语义(加号不能当作减号用,这样别人会误会的)

 


3.重载方式

3.1 重载为类的成员函数

? 定义  

返回类型 [类名::]operator 运算符(形参表) {}

      Complex      operator     +     (Complex op2);

一般是一个对象                           可以省略一个形参,另一个参数通过this指针隐式传递


class Complex
{
public:
Complex(
double=0.0,double=0.0);//constructor
Complexoperator+(const Complex &);//addition
private:
double real; //real part
double imaginary;//imaginary part
};
Complex Complex::
operator+(const Complex &operand2)
{
return Complex(real+operand2.real, imaginary+operand2.imaginary);
}

重载为成员函数时,参数个数为运算符目数-1

技术分享图片

 

 


Complex Complex::operator=(Complex c2)
{
real
= c2.real;
imag
= c2.imag;
return *this; //指针的使用
}

?前缀与后缀运算符

技术分享图片


// Overload postfix ++ for Complex.
Complex Complex::operator++(int x) //后缀的话要传入一个参数加以区分
{
Complex r
= *this; //要新建一个指针
real++;
imag
++;
return r;
}
// Overload prefix ++ for Complex.
Complex Complex::operator++() //前缀的话就是普通的,默认是前缀的
{
++real;
++imag;
return *this; //直接返回就行
}
int main()
{
Complex a(
2,3), b(3, 4), c;
c
= a * b;
Complex d
= ++c; //但是可以看到在使用的时候没有区别
Complex e = d++; //后缀并不需要传递那个int
d.Output();
e.Output();
return 0;
}


3.2 重载为类的非成员函数(一般为友元函数)

? 定义

friend 返回类型 operator 运算符(形参表) {}

friend Complex operator     +    (Complex op1, Complex op2);

? 友元函数没有this指针,需给出所有传递参数

? 友元函数的操作灵活性

当运算符左右为不同类型数据时,比如a = 3 + b;,重载为类的成员函数无法实现


friend Complex operator+(float x, Complex c)
{
Complex r;
r.real
= x+c.real;
r.imag
= c.imag;
return r;
}


3.3 重载为普通函数


class Complex {
public:
  Complex( double r = 0.0, double i= 0.0 ){
    real = r;
    imaginary = i;
}
  double real;       // real part
  double imaginary;  // imaginary part
};

Complex operator+( const Complex & a ,const Complex & b)
{
return Complex( a.real+b.real,a.imaginary+b.imaginary);
}
Complex a(
1,2), b(2,3),c;
// “类名(参数表)”就代表个对象
c = a + b; // 等效于c = operator+(a,b);
重载为普通函数时,参数个数为运算符目数
注意:类的成员变量要为public(故用得少)


3.4 第一二种方式的比较

?一般,单目运算符(只接收一个操作数的运算符,如++)重载是类的成员函数,双目运算符(俩操作数,如a=b+c)重载为类的友元函数(另一个可以是数字)

 


 4.典型运算符重载

4.1 输入输出流:“<<”和“>>”只能以友元函数的方式重载


int main()
{
Complex a, b, c;
cin
>> a >> b; //实现直接输入输出
c = a * b;
Complex d
= ++c;
Complex e
= d++;
d
= d+1.01;
e
= 1.01+e;
cout
< e;
return 0;
}
friend istream
&operator>>(istream &in, Complex &c)//因为要改变值所以有引用
{
in >> c.real >> c.imag;
return in;
}
friend ostream
&operator<<(ostream &out, Complex c)
{
if(c.imag>0)
out <"+" <"i" << endl;
else
out <"i" << endl;
return out;
}


4.2 “=”

类似于浅拷贝&深拷贝

技术分享图片

 

 


4.3 “[ ]” :防止数组越界


float &Complex::operator[](int i) //要修改时,就要用引用
{
if (i==0) //实部是啥
return real;
else if(i==1)
return imag;
else
{
cout
<<"Out of boundary" << endl;
exit(
1);
}
}
int main()
{
Complex c(
3, 4);
cout
<0] <//输出实部
c[1] = 5;
cout
<< c;
c[
2] = 6; //一共就俩数,超了
}


4.4 “()”:自动执行和表达式中的使用

技术分享图片

 


 4.5 类型转换运算符:强制类型转化类的对象

技术分享图片

 


 5.运算符函数参数/返回类型

技术分享图片

 

 

技术分享图片


推荐阅读
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • 本文探讨了如何在模运算下高效计算组合数C(n, m),并详细介绍了乘法逆元的应用。通过扩展欧几里得算法求解乘法逆元,从而实现除法取余的计算。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 火星商店问题:线段树分治与持久化Trie树的应用
    本题涉及编号为1至n的火星商店,每个商店有一个永久商品价值v。操作包括每天在指定商店增加一个新商品,以及查询某段时间内某些商店中所有商品(含永久商品)与给定密码值的最大异或结果。通过线段树分治和持久化Trie树来高效解决此问题。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • C++: 实现基于类的四面体体积计算
    本文介绍如何使用C++编程语言,通过定义类和方法来计算由四个三维坐标点构成的四面体体积。文中详细解释了四面体体积的数学公式,并提供了两种不同的实现方式。 ... [详细]
  • 文件描述符、文件句柄与打开文件之间的关联解析
    本文详细探讨了文件描述符、文件句柄和打开文件之间的关系,通过具体示例解释了它们在操作系统中的作用及其相互影响。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
author-avatar
穿靴子的猫
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有