C++重载与多态
运算符重载
定义:运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。运算符重载的实质就是函数的重载。
优点:可以改变现有运算符的操作方式,以用于类类型,使得程序看起来更加直观。
·运算符重载的规则
(1)c++中的运算符除了少数几个之外,全部可以重载,而且只能重载c++中已经有的运算符。
(2)重载之后运算符的优先级和结合性都不会变。
(3)运算符重载是针对新类型数据的实际需要,对原有的运算符进行适当改造。一般来讲,重载功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。
注意:有些操作符是不能重载的,它们是类属关系运算符“.”、成员指针运算符“.*”、作用域分辨符“::”和三目运算符"?:"。
运算符重载分类:1.重载为类的非静态成员函数。2.重载为非成员函数
语法形式:
返回类型 operator 运算符(形参表) { 函数体; }
提示:当以非成员函数形式重载运算符时,有时需要访问运算符参数所涉及类的私有成员,这时可以把该函数声明为类的友元函数。当运算符重载为类的成员函数时,函数的参数个数比原来的操作数个数要少一个(后置“++”“--”除外),当重载为非成员函数时,参数个数与原操作数个数相同
·运算符重载为成员函数
对于双目运算符B,如果要重载为类的成员函数,使之能够实现表达式oprd1 B oprd2,其中oprd1为A类的对象,则应当把B重载为A类的成员函数,该函数只有一个形参,形参类型是oprd1.operator B(oprd2)。
*对于后置运算符如“++”、“--”,如果要将它们重载为类的成员函数,用来实现表达式oprd++或oprd--,其中oprd为A类的对象,那么运算符就应当重载为A类的成员函数,这时函数要带有一个整型(int)形参。这里的int类型参数在运算中不起任何作用,只是用于区别后置++--与前置++--。
例1:复数类加减法运算重载
#include<iostream> using namespace std; class Complex //复数类定义 { public: //外部接口 Complex(double r=0.0,double i=0.0):real(r),imag(i){} //构造函数 Complex operator+(const Complex &c2)const; //运算符+重载成员函数 Complex operator-(const Complex &c2)const; //运算符-重载成员函数 void display() const; //输出复数 private: //私有数据成员 double real; //复数实部 double imag; //复数虚部 }; Complex Complex::operator+(const Complex &c2)const //重载运算符函数实现 { return Complex(real + c2.real, imag + c2.imag); //创建一个临时无名对象作为返回值 } Complex Complex::operator-(const Complex &c2)const { return Complex(real - c2.real, imag - c2.imag); } void Complex::display()const { cout << "(" << real << "," << imag << ")" << endl; } int main() { Complex c1(5, 4), c2(2, 10), c3; cout << "c1="; c1.display(); cout << "c2="; c2.display(); c3 = c1 - c2; cout << "c3=c1-c2="; c3.display(); c3 = c1 + c2; cout << "c3=c1+c2="; c3.display(); system("pause"); return 0; }
运算结果:
本例重载的“+”,“-”函数中,都是创建一个临时的无名对象作为返回值,它的含义是:调用Complex构造函数创建一个临时对象并返回它。也可以如下进行返回:
Complex Complex::operator+(const Complex &c2)const { Complex c(real+c2.real,imag+c2.imag); return c; }
例2:前置++与后置++
#include<iostream> using namespace std; class Point { public: Point(double r = 0.0, double i = 0.0) //:real(r), imag(i) { } { real = r; imag = i; } Point& operator++(); Point operator++(int); void display() const; private: double real; double imag; }; void Point::display() const { cout << real << ' ' << imag << endl; } Point & Point::operator++() { real++; imag++; return *this; } Point Point::operator++(int) { Point old = *this; ++(*this); return old; } int main() { Point point(1, 2); (point++).display(); (++point).display(); system("pause"); return 0; }
运行结果如图:
那么将操作符重载函数同时进行引用会怎么样呢
将
Point& operator++(); Point operator++(int);
改为
Point& operator++(); Point& operator++(int);
代码运行截图
但是运行出错,那是因为后置++加了引用符号之后会导致old释放后无法接收,需要另外定义一个对象接收old值来进行输出。
完整代码如下
#include<iostream> using namespace std; class Point { public: Point(double r = 0.0, double i = 0.0) //:real(r), imag(i) { } { real = r; imag = i; } Point& operator++(); Point& operator++(int); void display() const; private: double real; double imag; }; void Point::display() const { cout << real << ' ' << imag << endl; } Point & Point::operator++() { real++; imag++; return *this; } Point & Point::operator++(int) { Point old = *this; ++(*this); return old; } int main() { Point point(1, 2),b; (++point).display(); b = point++; b.display(); system("pause"); return 0; }
运行结果如图:
后置++加了引用符号之后会导致old释放后无法接收,需要另外定义一个对象接收old值来进行输出。
·运算符重载为非成员函数
例:重载+-<<
#include<iostream> using namespace std; class Complex { public: Complex(double r = 0.0, double i = 0.0) :real(r), imag(i){} friend Complex operator+(const Complex &c1, const Complex &c2); friend Complex operator-(const Complex &c1, const Complex &c2); friend ostream & operator<<(ostream &out, const Complex &c); private: double real; double imag; }; Complex operator+(const Complex &c1, const Complex &c2) { return Complex(c1.real + c2.real, c1.imag + c2.imag); } Complex operator-(const Complex &c1, const Complex &c2) { return (c1.real - c2.real, c1.imag - c2.imag); } ostream & operator<<(ostream &out, const Complex &c) { out << "(" << c.real << "," << c.imag << ")"; return out; } int main() { Complex c1(5,4),c2(2,10),c3; cout << "c1=" << c1 << endl; cout << "c2=" << c2 << endl; c3 = c1 - c2; cout << "c3=c1-c2=" << c3 << endl; c3 = c1 + c2; cout << "c3=c1+c2=" << c3 << endl; system("pause"); return 0; }
运行截图
分析:将运算符重载为类的非成员函数,就必须把操作数全部通过形参的方式传递给运算符重载函数。
原文地址:https://www.cnblogs.com/Zzzzxy/p/11744106.html
- 在Mapx中设置单个图元的样式
- silverlight之deeplink学习笔记
- Mapx实现双标注
- Silverlight中也玩屏幕截图
- 在虚拟机上进行网络数据包分析
- TiDB 1.1 Alpha Release
- 重温delphi之:如何将Bitmap位图与base64字符串相互转换
- base64编码在silverlight中的使用
- silverlight中如何将BitmapImage转化为Stream或byte数组?
- Centos6.8下编译安装LAMP的操作记录梳理
- Linux下批量管理工具pssh使用记录
- salt-ssh批量操作记录
- 用AutoHotKey建立自己的便签本
- Flash/Flex学习笔记(14):制作涂鸦板
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Firefox 31~34远程命令执行漏洞的分析
- emlog绕过验证码刷评论
- cmseasy最新注入+360webscan的绕过分析
- 新型任意文件读取漏洞的研究
- Chrome XSS Auditor Bypass Using SVG
- ngx_lua_waf针对性改写
- Wordpress < 4.1.2 存储型XSS分析与稳定POC
- 重构Sec-News之路
- ThinkPHP留后门技巧
- 『三个白帽』某题的writeup
- 创造tips的秘籍——PHP回调后门
- Joomla远程代码执行漏洞分析(总结)
- 那些年我拿下的demo站之方维O2O
- emlog自动备份插件泄露整站数据库备份漏洞
- md5(unix)原理分析