热门标签 | 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.运算符函数参数/返回类型

技术分享图片

 

 

技术分享图片


推荐阅读
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 本文介绍了如何通过Java代码计算一个整数的位数,并展示了多个基础编程示例,包括求和、平均分计算、条件判断等。 ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • ListView简单使用
    先上效果:主要实现了Listview的绑定和点击事件。项目资源结构如下:先创建一个动物类,用来装载数据:Animal类如下:packagecom.example.simplelis ... [详细]
  • 本文详细介绍了get和set方法的作用及其在编程中的实现方式,同时探讨了点语法的使用场景。通过具体示例,解释了属性声明与合成存取方法的概念,并补充了相关操作的最佳实践。 ... [详细]
  • 探讨 HDU 1536 题目,即 S-Nim 游戏的博弈策略。通过 SG 函数分析游戏胜负的关键,并介绍如何编程实现解决方案。 ... [详细]
  • Python + Pytest 接口自动化测试中 Token 关联登录的实现方法
    本文将深入探讨 Python 和 Pytest 在接口自动化测试中如何实现 Token 关联登录,内容详尽、逻辑清晰,旨在帮助读者掌握这一关键技能。 ... [详细]
  • 通常情况下,修改my.cnf配置文件后需要重启MySQL服务才能使新参数生效。然而,通过特定命令可以在不重启服务的情况下实现配置的即时更新。本文将详细介绍如何在线调整MySQL配置,并验证其有效性。 ... [详细]
  • Android 6.0 切换指定 Wi-Fi 的解决方案
    本文详细介绍了在 Android 6.0 系统中切换到指定 Wi-Fi 的方法,包括常见的问题、原因分析及解决方案。通过官方文档和代码示例,帮助开发者更好地理解和实现这一功能。 ... [详细]
  • Python自动化测试入门:Selenium环境搭建
    本文详细介绍如何在Python环境中安装和配置Selenium,包括开发工具PyCharm的安装、Python环境的设置以及Selenium包的安装方法。此外,还提供了编写和运行第一个自动化测试脚本的步骤。 ... [详细]
  • 本篇文章介绍如何将两个分别表示整数的链表进行相加,并生成一个新的链表。每个链表节点包含0到9的数值,如9-3-7和6-3相加得到1-0-0-0。通过反向处理链表、逐位相加并处理进位,最终再将结果链表反向,即可完成计算。 ... [详细]
  • 本文探讨了C++编程中理解代码执行期间复杂度的挑战,特别是编译器在程序运行时生成额外指令以确保对象构造、内存管理、类型转换及临时对象创建的安全性。 ... [详细]
  • Java中的基本数据类型与包装类解析
    本文探讨了Java编程语言中的8种基本数据类型及其对应的包装类。通过分析这些数据类型的特性和使用场景,以及自动拆装箱机制的实现原理,帮助开发者更好地理解和应用这些概念。 ... [详细]
  • 本文详细介绍了 Android 开发中 layout_gravity 属性的使用方法及其在不同布局下的效果,旨在帮助开发者更好地理解和利用这一属性来精确控制视图的布局。 ... [详细]
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社区 版权所有