(一二二)运算符重载——第十一章
来源:互联网 发布:淘宝搜索的算法 编辑:程序博客网 时间:2024/05/21 19:41
本章重点是类设计技术,而不是通用原理。
C++的重点是多使用。
正如我之前写了这么多的学习笔记一样,几乎绝大部分的代码,都是我根据书上的知识,然后理解自行再创造写下的。虽然遇见了不少问题,但解决后,下次再遇见这类情况,解决起来很轻松,绝大多数都可以直接靠记忆书写代码,即使个别忘记了,回头翻一番笔记,基本也能解决,需要靠百度去解决的,已经很少了。
运算符重载是一种形式的C++多态(就像函数重载那样,同名但调用不同的函数)。
要重载运算符,需要使用被称为运算符函数的特殊函数形式。运算符函数格式如下:
operator 运算符 (argument-list);
例如:operator +(); 表示重载加号运算符,而operator -()表示重载减号运算符。
其中,运算符必须是有效的C++运算符,而不是是自己捏造的(例如+-*/之类就是有效的,而@就是无效的)。
但需要注意的是,定义运算符有时需在类中定义(非必须,具体看下面的运算符重载的限制),对该类对象有效。运算符前面是的调用该方法的对象,参数中是被调用的对象。
例如:
class Mm{int a;public:...... ;Mm operator + (const Mm &bb){return this->a + bb.a;}}
这里实际上就是把+号运算符重载为对对象有用的加号运算符了。
如代码:
#include<iostream>#include<string>class Skill//技能类{std::string name;//技能名称double jilv;//几率double dam;//伤害public:Skill(std::string name_ = "无技能", double jilv_ = 0.0, double dam_ = 0.0) { name = name_;jilv = jilv_;dam = dam_; }//默认构造函数,默认几率和伤害都为0void show();Skill operator +(const Skill&b);//技能融合函数,将2个技能融合起来变成第三个技能};int main(){using namespace std;Skill one("拔刀斩", 20, 500);Skill two("半月斩", 15, 400);one.show();two.show();Skill three = one + two;//新对象为两个对象之和cout << "技能已融合!新技能get!" << endl;three.show();system("pause");return 0;}void Skill::show(){std::cout << "技能:" << name << " 的发动几率为 " << jilv << " %,伤害为: " << dam << " 点。" << std::endl;}Skill Skill::operator+(const Skill&b){Skill another;another.name = name;//名字延续加号前的another.jilv = (jilv + b.jilv)*1.25;//几率为两个几率之和,乘以1.2if (another.jilv > 100)another.jilv = 100;//如果几率大于100,则为100another.dam = dam + b.dam*0.5;//伤害为第一个伤害加上第二个伤害的一半return another;//返回对象(不是引用)}
输出:
技能:拔刀斩 的发动几率为 20 %,伤害为: 500 点。技能:半月斩 的发动几率为 15 %,伤害为: 400 点。技能已融合!新技能get!技能:拔刀斩 的发动几率为 43.75 %,伤害为: 700 点。请按任意键继续. . .
总结:
①运算符重载的关键,是运算符左边的调用重载函数,右边的作为参数,所以在码代码的时候,需要注意顺序。
例如,one+two时,按照类方法,新对象three是one的名字,如果是two+one,新对象three是two的名字。
当然,具体是什么,根据函数定义来决定。
运算符重载的限制:
多数C++运算符(参见表11.1,如下图,不过看不清……)都可以用这样的方式重载。
ps:图看不清,不传了。具体请看书(最好看实体书,pdf版不是很清楚,不过大部分都可以重载)但也有一些限制,例如:重载的运算符不必是成员函数,但必须至少有一个操作数是用户定义的类型。
具体限制如下:
①重载后的运算符,必须至少有一个操作数是用户定义的类型(否则不知道你使用的是运算符重载,在运算符重载的函数定义里,也容易出问题),这将防止用户为标准类型重载运算符。
因此,不能把减法运算符重载为2个标准类型(如int或者double)的值的和,而不是他们的差。
②使用运算符时不能违反运算符原来的句法规则。例如,+-*/以及%这五种运算符,需要两个数来参与。你不能只给他用一个数。例如a+b是可以的,但是+a这种是不行的。而像地址运算符&就是只对一个数使用,如&dizhi。
另外,运算符即使被重载,其运算优先级也与原来的运算符的优先级相同,例如a+b/c,即使对+进行运算符重载,也依然是先计算b/c,再计算a+ (b/c)的结果。
③不能创建新的运算符,只能用已有的
④不能重载下面的运算符。
(1)sizeof sizeof运算符
(2). ←这是一个句号,成员运算符,比如结构名.结构内变量
(3).* ←句号和乘号,成员指针运算符(没见过)
(4):: ←两个冒号,作用域解析运算符
(5)?: 条件运算符,比如: a>b?c:d
(6)typeid ←一个RTTI运算符(没见过)
(7)const_cast ←强制类型转换运算符(没见过这种用法)
(8)dynamic_cast ←强制类型转换运算符(没见过这种用法)
(9)reinterpret_cast ←强制类型转换运算符(没见过这种用法)
(10)static_cast ←强制类型转换运算符(没见过这种用法)
而上面那个图片中的运算符,基本都可以用(反正大部分都能用,不能用的是少数)。
⑤大部分运算符:可以通过成员、非成员函数进行重载;
以下几个运算符,只能通过成员函数进行重载:
(1)= ←赋值运算符
(2)() ←函数调用运算符
(3)[] ←下标运算符(为什么叫下标?)
(4)-> ←通过指针访问类成员的运算符(不懂,是指this->私有成员这样么?)
⑥运算符重载最好遵循一般逻辑,例如不要把加法运算符(+)重载为两个对象各个值的差这种违反直觉的事情。
⑦重载运算符面对不同对象时,需要定义不同类型的重载运算符函数。
例如,一个对象 + 另一个对象,和一个对象 + 一个int值/double值,是不能使用同一个函数的。
如代码:
#include<iostream>#include<string>class Skill//技能类{std::string name;//技能名称double jilv;//几率double dam;//伤害public:Skill(std::string name_ = "无技能", double jilv_ = 0.0, double dam_ = 0.0) { name = name_;jilv = jilv_;dam = dam_; }//默认构造函数,默认几率和伤害都为0void show()const;Skill operator +(const Skill&b)const;//技能融合函数,将2个技能融合起来变成第三个技能void operator*=(const double &b);//技能增强函数,重载运算符*=void operator/=(const double &b);//另一种形式的增强,通过降低概率增加伤害,重载运算符/=};int main(){using namespace std;Skill one("拔刀斩", 20, 500);Skill two("半月斩", 15, 400);one.show();two.show();Skill three = one + two;//新对象为两个对象之和cout << "技能已融合!新技能get!" << endl;three.show();cout << "现将增强你的技能,增强发动几率和伤害,增加比例为1.5。" << endl;three *= 1.5;//重载*=运算符three.show();cout << "现在将降低概率,增强伤害,系数为:2" << endl;three /= 2;//重载/=运算符three.show();cout << "bye." << endl;system("pause");return 0;}void Skill::show()const{std::cout << "技能:" << name << " 的发动几率为 " << jilv << " %,伤害为: " << dam << " 点。" << std::endl;}Skill Skill::operator+(const Skill&b)const{Skill another;another.name = name;//名字延续加号前的another.jilv = (jilv + b.jilv)*1.25;//几率为两个几率之和,乘以1.2if (another.jilv > 100)another.jilv = 100;//如果几率大于100,则为100another.dam = dam + b.dam*0.5;//伤害为第一个伤害加上第二个伤害的一半return another;//返回对象(不是引用)}void Skill::operator*=(const double &b){jilv *= b;//几率和伤害都乘以系数dam *= b;}void Skill::operator/=(const double &b){jilv /= b;//几率除系数dam *= b;//伤害乘系数}
输出:
技能:拔刀斩 的发动几率为 20 %,伤害为: 500 点。技能:半月斩 的发动几率为 15 %,伤害为: 400 点。技能已融合!新技能get!技能:拔刀斩 的发动几率为 43.75 %,伤害为: 700 点。现将增强你的技能,增强发动几率和伤害,增加比例为1.5。技能:拔刀斩 的发动几率为 65.625 %,伤害为: 1050 点。现在将降低概率,增强伤害,系数为:2技能:拔刀斩 的发动几率为 32.8125 %,伤害为: 2100 点。bye.请按任意键继续. . .
- (一二二)运算符重载——第十一章
- 第十一章(11.1——11.7)小结:运算符重载
- C++找对象的季节(补)——运算符重载一二事
- C++程序设计语言--第十一章:运算符重载
- (一二五)第十一章复习题
- (一二六)第十一章编程练习
- C++编程思想读书笔记之 第十一章 运算符重载
- C++——运算符重载(二)
- C++笔记——c++编程思想(上)第十一、十二、十三章 引用和拷贝构造函数,运算符重载,继承组合等
- 《C++编程思想》 第十一章 运算符重载 (原书代码+习题+解答)
- C++运算符重载(二)——使用方法
- C++运算符重载(二)——使用方法
- C++运算符重载(二)——使用方法
- 多态性——运算符重载(二)
- 运算符重载(二)
- 运算符重载(二)
- 第十一讲:运算符重载与重载函数
- 第十一讲:运算符重载与重载函数
- <LeetCode><Easy> 328. Odd Even Linked List
- POJ 1077 Eight(八数码第八境界|IDA*+曼哈顿距离+判断是否有解)
- 八数码的几种做法的总结以及是否有解的判断
- leetCode 226. Invert Binary Tree
- **LeetCode 60. Permutation Sequence
- (一二二)运算符重载——第十一章
- Android Studio——SAX解析XML
- (一二二)友元函数
- Learning how to learn(1)
- Linux(Ubuntu, Fedora, Vmware)使用笔记(1)
- Final Keyword In Java
- (一二三)矢量坐标计算
- (一二四)给类对象赋值、以及类对象的返回值
- Linux硬链接和符号链接的区别