第十一讲 运算符重载 与类型转换.

Slides:



Advertisements
Similar presentations
XX啤酒营销及广告策略.
Advertisements

第9章 重载.
跳楼价 亏本大甩卖 清仓处理 买一送一 5折酬宾. 跳楼价 亏本大甩卖 清仓处理 买一送一 5折酬宾.
清仓处理 跳楼价 满200返160 5折酬宾.
第九讲 类与对象 (I)面向对象基础.
北师大版七年级数学 5.5 应用一元一次方程 ——“希望工程”义演 枣庄市第三十四中学 曹馨.
第14章 c++中的代码重用.
第八章 类和对象.
海洋存亡 匹夫有责 ——让我们都来做环保小卫士 XX小学三(3)班.
Object-Oriented Programming in C++ 第四章 运算符重载
C++语言程序设计 第四章 类与对象 成都信息工程学院计算机系.
4.1 概述 4.2 类与对象的实现 4.3 对象的初始化和析构 4.4 类的包含 4.5 类模板
Derived Class 前言 衍生類別的定義 單一繼承 public, protected, 和 privated 基底類別
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
第11章 运算符重载 什么是运算符重载 运算符重载的方法 几个特殊的运算符的重载 自定义类型转换运算符 运算符重载实例.
哈夫曼编码.
西安交通大学 计算机教学实验中心 大学C++程序设计教程 西安交通大学 计算机教学实验中心
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序设计期末复习 黎金宁
刘胥影 东南大学计算机学院 面向对象程序设计1 2010~2011第3学期 刘胥影 东南大学计算机学院.
辅导课程六.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
类类型 C++支持的内置类型和操作,如 int i=10; i=i%6; i=i+4;
第九章 多态性 丘志杰 电子科技大学 计算机学院 软件学院.
第二章 Java语言基础.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
第七章 操作符重载 胡昊 南京大学计算机系软件所.
10 多載函數 10.1 多載概論 多載一般函數 多載成員函數 10-3
第十三讲 文件流与 输出输入重载.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C++大学基础教程 第11章 多态性 北京科技大学 信息基础科学系 2019/4/8 北京科技大学.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
$9 泛型基础.
第14讲 运算符重载 运算符重载的概念、方法和规则 运算符重载作为类的成员函数 运算符重载作为类的友元函数 特殊运算符的重载 类型转换函数.
C#面向对象程序设计 $6 深入理解类.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
补课.
第10讲 构造函数和析构函数 构造函数 析构函数 This 指针.
保留字與識別字.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++大学基础教程 第10章 运算符重载 北京科技大学 2019/5/7 北京科技大学.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
第九节 赋值运算符和赋值表达式.
3.16 枚举算法及其程序实现 ——数组的作用.
C++程序设计基础 主讲人:谢昕 华东交通大学信息工程学院 第十~十二讲 多态性和虚函数 2005年春季学期.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
第 9 章 建構函式與解構函式.
辅导课程十五.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
第二章 Java基本语法 讲师:复凡.
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
程序设计基础A(C语言) 第一章 C语言概述 主讲教师: 许 康
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
第17章 运算符重载 一、运算符重载的概念 二、禁止重载的运算符 三、运算符重载的规则 四、单目运算符函数 五、双目运算符函数.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
基本知识 数据类型、变量、常量、运算符.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
鸡兔同笼(续) ——选择结构.
第二章 数据类型与表达式 丘志杰 电子科技大学 计算机学院 软件学院.
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
第十四讲 文件流与 输出输入重载.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
本节内容 this指针 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Presentation transcript:

第十一讲 运算符重载 与类型转换

运算符重载 类型转换 为什么要“运算符重载” 那些运算符可以重载,哪些不可以 如何实现运算符重载 实现方式:成员函数与非成员函数 怎样实现对象与基本数据类型数据的运算

为什么要运算符重载 如何 实现? 预定义的运算符只针对基本数据类型,若要对类的对象进行类似的运算,需要重新定义运算符的功能。 运算符重载实质就是函数重载: 对已有的运算符赋予多重含义,使得同一个运算符作用于不 同类型的数据时导致不同的行为。 例: int x=1, y=2, z; z = x + y; // 普通数据类型的加法 Point A(1,2), B(3,4), C; C = A + B; // Point 类对象的加法 如何 实现? String str1(“hello”), str2(“Math”), str3; str3 = str1 + str2; // String 类对象的加法

运算符重载基本规则 不能被重载的四个运算符: . .* :: ?: 只能重载已有的运算符 重载不改变运算符的优先级和结合率 运算符重载不改变运算符的操作数的数目 重载的功能通常与已有的功能类似 运算符重载是针对新类型数据(类与对象)的需要, 因此 至少有一个操作数是新类型数据 不能被重载的四个运算符: . .* :: ?:

如何实现运算符重载 定义运算符重载的一般形式 这里的类型说明符可以是类名或基本数据类型 类型说明符 operator运算符(形参列表) { 函数体; } // 在类的声明中定义 类型说明符 类名::operator运算符(形参列表) { 函数体; } // 假定在外部定义 这里的类型说明符可以是类名或基本数据类型 例: Complex Complex::operator+(Complex & c2) { return Complex(real+c2.real, imag+c2.imag); }

实现方式一:成员函数方式 运算符重载可以通过成员函数实现 运算符重载为成员函数时,形参个数少一个: 目的对象自动作为第一个操作数/左操作数 运算符重载为成员函数时,形参个数少一个: 目的对象自动作为第一个操作数/左操作数 如果是单目运算,无需形参(后置 ++ 和后置 -- 除外) 优点:可以自由访问本类的数据成员 若是双目运算,则左操作数就是目的对象本身 若是单目运算,则目的对象就是操作数,不需要其它对象

例:有理数的加法 class Rational { public: Rational() { x=0; y=1; } Rational(int x, int y) { this->x=x; this->y=y; } Rational operator+(const Rational & p); private: int x, y; }; Rational Rational::operator+(const Rational & p) { int newx = x*p.y + y*p.x; int newy = y*p.y; return Rational(newx, newy); } ex11_overload01.cpp

实现方式一:成员函数 双目运算符的重载(成员函数) 对象A ⊙ 对象B 声明 类型说明符 operator⊙(const 类名 &); 定义 类型说明符 类名::operator⊙(const 类名 &p) { 函数体; } 定义 (在类外部定义) 重载双目运算符 ⊙(成员函数): 只有一个形参(对象)

实现方式一:成员函数 前置单目运算符的重载(成员函数) ⊙ 对象A 声明 类名 operator⊙(); { 函数体; } 定义 (在类外部定义) 重载前置单目运算符 ⊙(成员函数方式):没有形参

实现方式一:成员函数 后置单目运算符(++、--)的重载(成员函数) 对象A ⊙ 类名 operator⊙(int); 声明 类名 类名::operator⊙(int dummy) { 函数体; } 定义 (在类外部定义) 重载后置单目运算符 ⊙(成员函数方式): 带一个整型形参,该形参在运算中不起任何作用,只用于区分前置和后置,因此也称为伪参数。

例:重载单目运算符 class Clock { public: Clock(int H=0, int M=0, int S=0); void showTime() const // 显示时间 { cout<<hour<<":"<<minute<<":"<<second<<endl;} Clock operator++(); // 前置单目运算符重载 Clock operator++(int); // 后置单目运算符重载 private: int hour, minute, second; }; Clock::Clock(int H, int M, int S) // 构造函数 { if(0<=H && H<24 && 0<=M && M<60 && 0<=S && S<60) { hour = H; minute = M; second = S; } else cout<<"Time error!"<<endl; }

例:重载单目运算符 Clock Clock::operator++() // 前置单目运算符重载函数 { second++; if(second >= 60) { second -= 60; minute++; if(minute >= 60) { minute -= 60; hour = (++hour) % 24; } } return *this; Clock Clock::operator++(int) // 后置单目运算符重载 { // 注意形参表中的整型参数 Clock old=*this; ++(*this); // 调用前置++ return old; ex11_overload02.cpp

实现方式二:非成员函数 非成员函数方式实现运算符重载 - 在相关类中将其声明为友元函数,在类外部定义 - 形参个数与操作数相同 - 所有操作数都通过参数传递 例: Complex operator+(const Complex &c1, const Complex &c2) { return complex(c1.real+c2.real, c1.imag+c2.imag); }

例:有理数的减法 class Rational { public: Rational() { x=0; y=1; } Rational(int x, int y) { this->x=x; this->y=y; } friend Rational operator-(const Rational &p1, const Rational &p2); private: int x, y; }; Rational operator-(const Rational &p1, const Rational &p2) { int newx = p1.x*p2.y – p1.y*p2.x; int newy = p1.y*p2.y; return Rational(newx, newy); } ex11_overload03.cpp

重载 [] 为什么要重载 [ ] 在数组中,可以通过 [ ] 来引用指定位置的元素。在 Rational 类中,我们希望用 a[0] 表示分子,a[1] 表示分母。 int Rational::operator[](int idx) { if (idx == 0) return x; else return y; } Rational a(4,5); cout << a[0] << “/” << a[1] << endl; // OK a[0] = 3; // ???

左值 什么是左值? 能出现在赋值号左边的量称为左值(Lvalue) 怎样使得 r[0] 能出现在赋值号左边? 返回 r[0] 的引用 int & Rational::operator[](int idx) { if (idx == 0) return x; else return y; } ex11_overload04.cpp

自动类型转换 怎样实现对象与基本数据类型变量的运算 自动/隐式类型转换 对象  基本数据类型 基本数据类型  对象

基本数据类型对象 例:有理数与整型数据的加法运算 通过构造函数,将整型数据自动转换为有理数,然后参与运算 Rational a(1,2), b; int c=3; b = a + c; // 怎么实现? 通过构造函数,将整型数据自动转换为有理数,然后参与运算 class Rational { public: Rational() { x=0; y=1; } Rational(int x, int y) { this->x=x; this->y=y; } Rational(int x) { this->x=x; y=1; }; ... ... private: int x, y; }; ex11_overload05.cpp

对象基本数据类型 没有返回数据类型! 实现方式:重载类型转换函数(只能作为成员函数) 例:有理数与双精度数的加法运算 Rational a(1,2); double b=0.8, c; c = a + b; // 怎么实现? 将有理数转换为双精度数,然后参与运算 实现方式:重载类型转换函数(只能作为成员函数) operator 转换函数名() { 函数体 }; 没有返回数据类型! 类名::operator 转换函数名() { 函数体 }; // 假定在外部定义

例:自动类型转化 class Rational { public: Rational() { x=0; y=1; } Rational(int x, int y) { this->x=x; this->y=y; } operator double(); private: int x, y; }; Rational::operator double() { return double(x)/y; } ex11_overload06.cpp

一个类可以重载类型转换函数实现对象到基本数据 类型的转换,也可以转换构造函数实现基本数据类 型到对象的转换,但两者不能并存! 自动类型转换注意点 一个类可以重载类型转换函数实现对象到基本数据 类型的转换,也可以转换构造函数实现基本数据类 型到对象的转换,但两者不能并存! 若重载了类型转换函数,则建议用非成员函数方式 实现运算符重载,并且形参使用“常引用”! Rational operator+ {const Rational &r1, const Rational &r2}

重载运算符建议 运算符 []、++、 --、 () 必须以成员函数方式重载 运算符 <<、>> 必须以非成员函数重载 (这两个运算符的重载涉及到输入输出,将在文件流中介绍) 算术运算符和关系运算符建议以非成员函数重载,以便实现一些简单的自动类型转换

上机作业 课后练习(自己练习) 1) 使用成员函数方式重载复数类的加法和减法,使之能执行下面的运算 (程序取名 hw11_01.cpp) Complex a(2.1,5.7), b(7.5,8), c, d; c = a + b; d = b + 5.6; 思考:能否实现 c = 4.1 + a? 2) 使用非成员函数方式重载复数的加法和减法运算,使之能执行下面的运算 (程序取名 hw11_02.cpp) Complex a(2.1,5.7), b(7.5,8), c, d; c = a + b; d = b + 5.6; e = 4.1 + a;

上机作业 3) 使用成员函数方式重载有理数的比较运算,即 >, ==, < (程序取名 hw11_03.cpp) Rational a(4,5), b(2,3); cout << "a>b? " << (a>b ? "true" : "false") << endl; cout << "a==b? " << (a==b ? "true" : "false") << endl; cout << "a<b? " << (a<b ? "true" : "false") << endl;