第六章 簡介運算子超載 (Operator Overloading)

Slides:



Advertisements
Similar presentations
第一單元 建立java 程式.
Advertisements

桃園市都市設計審議(暨建照預審)報告書 案 名:申請單位 / 行政區 / 地段號 / 工程類型/變更設計次數 送審依據:
Memory Pool ACM Yanqing Peng.
第11章 使用类.
高级语言程序设计 C++程序设计教程(下) 2006年春季学期 与一些教材的区别 偏重理论,不去讨论某个系统的具体使用方法,但会涉及实现技术
第十一章 (上篇) 函數樣板(Function Template) 與 類別樣板(Class Template)
走向C++之路 WindyWinter WindyWinter感谢诸位前来捧场。
Visual C++ introduction
簡易C++除錯技巧 長庚大學機械系
内容提要 对象的生命周期 构造函数 析构函数 拷贝构造函数. 常宝宝 北京大学计算机科学与技术系
Chap 18 類別與物件 夫有土者,有大物也。有大物者,不可以物。 物而不物,故能物物。 明乎物物者之非物也,豈獨治天下百姓而已哉!
4.1 概述 4.2 类与对象的实现 4.3 对象的初始化和析构 4.4 类的包含 4.5 类模板
Derived Class 前言 衍生類別的定義 單一繼承 public, protected, 和 privated 基底類別
Chap 3 堆疊與佇列 Stack and Queue.
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
第11章 运算符重载 什么是运算符重载 运算符重载的方法 几个特殊的运算符的重载 自定义类型转换运算符 运算符重载实例.
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
第七章 搜索结构 静态搜索结构 二叉搜索树 AVL树.
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
哈夫曼编码.
第六章 继承性和派生类 胡昊 南京大学计算机系软件所.
刘胥影 东南大学计算机学院 面向对象程序设计1 2010~2011第3学期 刘胥影 东南大学计算机学院.
類別樣板 Class Template 類似函式樣板 由類別樣板產生的類別稱為類別樣版的實體(instance)
Operator Overloading; String and Array Objects
西安交通大学 计算机教学实验中心 大学C++程序设计教程 西安交通大学 计算机教学实验中心
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
C語言簡介 日期 : 2018/12/2.
Object-Oriented Programming in C++ 第一章 C++的初步知识
程序设计期末复习 黎金宁
Class(二) Overloaded Operators User-Defined Conversions 前言 超載運算子
第三章 C++中的C 面向对象程序设计(C++).
第12章 從C到C++語言 12-1 C++語言的基礎 12-2 C++語言的輸出與輸入 12-3 C++語言的動態記憶體配置
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
第四章 小技巧.
类类型 C++支持的内置类型和操作,如 int i=10; i=i%6; i=i+4;
Instructor Textbook Requirements TAs C++程式設計風格與藝術 (O’Reilly).
第七章 操作符重载 胡昊 南京大学计算机系软件所.
第一單元 建立java 程式.
10 多載函數 10.1 多載概論 多載一般函數 多載成員函數 10-3
Classes (2) Lecture 7.
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
常宝宝 北京大学计算机科学与技术系 数据结构(三) 常宝宝 北京大学计算机科学与技术系
第五章 递归与广义表 递归的概念 递归过程与递归工作栈 递归与回溯 广义表.
5 重複迴圈 5.1 增減運算符號 增量運算符號 減量運算符號
第10讲 构造函数和析构函数 构造函数 析构函数 This 指针.
OOP Recitation Course Speaker: Liu Yu-Jiun Date: 2009/3/25.
保留字與識別字.
第11章 從C到C++語言 11-1 C++語言的基礎 11-2 C++語言的資料型態與運算子 11-3 C++語言的輸出與輸入
第三章 数据抽象.
字符串 (String) 字符串是 n (  0 ) 个字符的有限序列, 记作 S = “c1c2c3…cn” 其中,S 是串名字
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
C++大学基础教程 第10章 运算符重载 北京科技大学 2019/5/7 北京科技大学.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
面向对象技术 练习 ffh.
C++程序设计基础 主讲人:谢昕 华东交通大学信息工程学院 第十~十二讲 多态性和虚函数 2005年春季学期.
三明治DIY.
C/C++基礎程式設計班 C++: 物件的使用、參考、重載函式 講師:林業峻 CSIE, NTU 3/28, 2015.
第1章 C++面向对象程序设计要点 1.1 函数和函数参数 1.2 输入输出   1.3 类 1.4 抽象类型和模板.
第 9 章 建構函式與解構函式.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
挑戰C++程式語言 ──第9章 函數.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
第 4 章 类的高级部分 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
Class 2005/05/25.
第四章 陣列、指標與參考 4-1 物件陣列 4-2 使用物件指標 4-3 this指標 4-4 new 與 delete
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
C++程序语言设计 Chapter 14: Templates.
Presentation transcript:

第六章 簡介運算子超載 (Operator Overloading) 6-1 運算子超載的基礎 6-2 超載二元運算子 6-3 超載邏輯與關係運算子 6-4 超載一元運算子 6-5 使用夥伴函數 6-6 細部檢視指定運算子 6-7 超載註標運算子

6-1 運算子超載的基礎 甚麼是運算子超載? 讓運算子(符號)有不同的意義 EX: 運算子的預設意義(以 + 與 = 為例) class frac {……} ; void main() { int x=5, y =3, z ; z = x + y ; // 使用‘=‘ ‘+’ int a[10], b[10], c[10]; c = a + b ; // 可乎??? frac f1(3,5), f2(2, 5), f3 ; f3 = f1 + f2 ; // 3/5 + 2/5 = 1, 可乎? } 可以重新定義+, = 運算子應用 在frac物件上的意義嗎?

如果沒有運算子超載能力 void main() { frac f1(3,5), f2(2, 5) , f3 ; f3.set(f1.add(f2)) ; // 模擬 f3 = f1 + f2 ; if (f1.great_equal(f2)) // f1 >= f2 cout << “ f1 >= f2” ; cout<<“f3=“; f3.print() ; // cout << “f3=“<<f3 ; }  也OK? 缺點? 你的看法

如何超載運算子 在類別中建立運算子函數(operator functions) 語法 class classname { …… // overload 運算子 X return-type operatorX(arg-list) { ……} }

運算子的種類 二元運算子(Binary Operators) 一元運算子 其他 EX: 5 + 3, 5>=3 … 算術運算: +, -, *, /, =, +=, -=,…., 關係運算: >, <, >=, <=… 邏輯運算: &&, ||, &, |, ^ 一元運算子 a++, --b, -c, +d 其他 [], (), new, delete, ->, ?:

6-2 超載二元運算子 範例一 class coord { int x, y ; …… } ; void main() { coord o1(10,10), o2(5,3), o3 ; o3 = o1 + o2; // o3  (15, 13) o3.print() ; //later, you can use cout << o3 ; }

超載運算子+, = class coord { int x, y ; …… } ; void main() { coord o1(10,10), o2(5,3), o3 ; o3.set(o1.add(o2)); // o3 = o1 + o2 ; o3.print() ; //later, you can use cout << o3 ; }

超載operator+, = o3.set(o1.add(o2)) ; temp = o1.add(o2) ; o3 = temp ; class coord { int x, int y; public: coord(){} coord(int a, int b){x=a; y=b;} coord add(coord c) { coord temp ; temp.x = this->x + c.x ; temp.y = this->y + c.y ; return temp ; } void set(coord c) { this->x = c.x; this->y=c.y; void print(){cout<<x<<y<<endl;} } ; o3.set(o1.add(o2)) ; temp = o1.add(o2) ; o3 = temp ;

超載operator+, = void main() { coord o1(10,10), o2(5,3), o3 ; // 原 o3.set(o1.add(o2)); o3.operator=(o1.operator+(o2)); } 超載operator+, = class coord { …… coord operator+(coord c) { //原add() coord temp ; temp.x = this->x + c.x ; temp.y = this->y + c.y ; return temp ; } void operator=(coord c) { // 原 set() this->x = c.x; this->y=c.y; } ;

超載operator+, = void main() { coord o1(10,10), o2(5,3), o3 ; // 原 o3.set(o1.add(o2)); // o3.operator=(o1.operator+(o2); o3 = o1 + o2 ; } 超載operator+, = class coord { …… coord operator+(coord c) { //原add() coord temp ; temp.x = this->x + c.x ; temp.y = this->y + c.y ; return temp ; } void operator=(coord c) { // 原 set() this->x = c.x; this->y=c.y; } ;

牢記運算式的真面目 o3 = o1 + o2 ; o3 = o1.operator+(o2) ; o3.operator=(o1.operator+(o2)) ;

回憶如何超載運算子 在類別中建立運算子函數(operator functions) 語法 class classname { …… // overload 運算子 X return-type operatorX(arg-list) { ……} }

將超載運算子定義在class外 class coord { …… coord operator+(coord c) ; void operator=(coord c) ; } ; coord coord::operator+(coord c) {…….} void coord::operator=(coord c) {……}

Yet Another Operator+ class coord { … coord operator+(const coord& ob2) { return coord(x+ob2.x, y+ob2.y) ; } };

範例二: 承範例一 新增 減號‘-’ 改善 operator=的功能(Copy constructor)

範例三: 需求 void main() { coord o1(10,10), o2(5, 3), o3 ; o3 = o1 + 2 ; } Q: o3=o1 +2 的真面目?

範例三(續) void main() { coord o1(10,10), o2(3,5), o3 ; o3 = o1 + 2 ; // o3 = o1.operator+(2) ; } class coord { int x, y ; public: coord() { x=y=0 ;} coord(int a) { x = a; y = 0 ;} coord(int a, int b) {x=a; y=b;} coord operator+(coord c) { ……} …… }

範例四: 請使用call by reference class coord { …… coord operator+(const coord& c) ; void operator=(const coord& c) ; } ; coord coord::operator+(const coord& c) {…} void coord::operator=(const coord& c) {…} 優點?

習題 class frac { int u, d ; public: // 定義+, -, *, /, % = 運算子 } ;

連加與連等 連加, OK? o4 = o1+o2+o3 ; 連等, OK? 參考範例二 o1=o2=o3; coord& operator=(const coord& c) { this->x = c.x; this->y=c.y; return *this; }

習題 為frac加入 +=, -=, *=, /=

6-3 超載邏輯與關係運算子 二元運算子(Binary Operators) 算術運算: +, -, *, /, =, +=, -=,…., 關係運算: >, <, >=, <=, ==… 邏輯運算: &&, ||, &, |, ^

範例一: Q: o1==o2的真面目? class coord { int x, y ; public: coord() {x = 0 ; y=0 ; } coord(int i, int j) { x=i; y=j;} bool operator==(const coord& ob2) ; bool operator&&(const coord& ob2) ; }; void main() { coord o1(10,10), o2(5,3) ; if (o1 == o2) cout << “o1 == o2” <<endl ; if (o1 && o2) cout << “as you wish….” <<endl ; } Q: o1==o2的真面目?

範例一(續) bool coord::operator==(const coord& ob2) { return (this->x==ob2.x) && (this->y==ob2.y); }

習題: 替frac加上==, >, <, >=, <= 運算子

6-4 超載一元運算子 一元運算子 需求: ++, --, +, - void main() { coord o1(10, 10), o2 ; o2 = ++o1 ; o1.print() ; // 前置++, prefix o2 = o1++ ; o1.print() ;//後置++, postfix } o1.operator++()

範例一: 前置++ class coord { int x, y ; public: …… coord operator++() { x++; y++ ; return *this; } Q1:為何不寫 void operator++()?

範例二: 如何分辨prefix與postfix ++ class coord { int x, y; public: coord(){} coord(int a, int b){x=a; y=b;} coord& operator++() { // prefix ++ x++; y++ ; return *this; } coord operator++(int) {//postfix ++ coord temp = *this ; x++; y++ ; return temp ; }; void main() { coord o1(10, 10), o2 ; o2 = ++o1 ; o2.print() ; // 前置++, prefix o2 = o1++ ; o2.print() ;//後置++, postfix } ++o1 ; o1++ ; // 解釋函數內容

範例三: 超載負號 class coord { coord& operator-() { x = -x; y =-y; return *this; } coord operator-(const coord& c) { …… } ; 這樣的operator-對嗎? try o1 = -o2 ; // o2(10,10)

習題: class frac 加入++, --, -

6-5 使用夥伴運算子函數 源起 o3 = o1+o2 ;  o3 = o1.operator+(o2) ; ????? 使用夥伴函數來定義運算子!

範例一: 記起來 參考 operator+(coord, coord) Q1:是否為class coord的成員? Q2:可否取用x, y ? 範例一: 記起來 #include<iostream.h> class coord { int x, y ; …… } ; coord operator+(coord ob1, coord ob2) { return coord(ob1.x+ob2.x, ob1.y+ob2.y) ; } void main() { coord o1(10,10), o2(5, 3), o3; o3 = o1 + o2 ; friend coord operator+(coord ob1, coord ob2) ; // o3 = operator+(o1, o2) ;

範例二: 10+ob2的解決 class coord{ int x, y ; public: coord(){x=0;y=0;} coord(int a){x=a;y=a;} coord(int a, int b){x=a;y=b;} friend coord operator+(coord ob1, coord ob2); void print(){cout<<x<<y<<endl;} } ;coord operator+(coord ob1, coord ob2) { return coord(ob1.x+ob2.x, ob1.y+ob2.y) ; } void main() { coord o1(10,10), o2(5, 3), o3; o3 = 10 + o2 ; // It’s OK, why ?}

範例三: 自己看 一元運算符號的負載 使用friend functions

很多個class的operator+ class coord { ……}; class frac {……} ; coord operator+(coord ob1, coord ob2) ; frac operator+(frac ob1, frac ob2) ; void main() { coord o1(10,10), o2(5,3), o3; o3 = o1 + o2 ; // 呼叫哪一個operator+ frac f1(5,3), f2(2,7), f3; f3 = f1 + f2 ; }

定義二元運算子函數的常態 Q: operator=需要用此種方式嗎? class frac { // 將以下之外部函數宣告成朋友函數 } ; frac operaotr+(const frac& f1, const frac& f2) {…} frac operaotr-(const frac& f1, const frac& f2) {…} frac operaotr*(const frac& f1, const frac& f2) {…} frac operaotr/(const frac& f1, const frac& f2) {…} bool operaotr==(const frac& f1, const frac& f2) {…} bool operaotr>(const frac& f1, const frac& f2) {…} ……

6-6 細部檢查指定運算子 operatr=要不要有回傳值? void operaotr=(const coord& ob); o1 = o2 = o3 ; // o1 = (o2=o3) ; o1.operator=(o2.operator=(o3)) ; 那要回傳什麼?

operator=的回傳值 class coord { … coord operator=(const coord& ob) { x = ob.x ; y = ob.y ; return ob ; }

operator=的回傳值 class coord { … coord& operator=(const coord& ob) { x = ob.x ; y = ob.y ; return ob ; }

operator=的回傳值 class coord { … coord& operator=(const coord& ob) { x = ob.x ; y = ob.y ; return *this ; } x y …. this

operator=的內容 class coord { coord& operator=(const coord& ob) { x = ob.x ; y = ob.y ; return *this; } } ; Q1: 不寫operator=會不會怎樣? 如 o1 = o2 ; bit-wise copy Q2: 那寫這個幹嘛? 當成員中有pointer時

範例一 與copy constructor幾乎相同! class strtype { char *p; int len ; …… } ; strtype& strtype::operator=(const strtype&ob){ if (&ob == this) return ; // what means? if (len < ob.len) { delete[] p; p = new char[ob.len+1] ;} len = ob.len ; strcpy(p, ob.p) ; return *this ; } Void main() { strtype s1(“Hello”),s2; S2=s1; ???? 與copy constructor幾乎相同!

6-7 超載註標運算子[] 需求 class SafeArray { int a[50] ; …… 但我可否使用: } ; void main() { SafeArray s ; cout << s.get(10) ; // cout << s.a[10] ; s.insert(10, 77) ; // s.a[10] = 77 ; … } 但我可否使用: cout << s[10]; s[10] = 77 ;

operator[] SafeArray s ; cout << s[10] ; // cout << s.operator[](10) ; s[10] = 77 ; // s.operator[](10) = 77 ; 奇怪, 怎麼會有寫在等號左邊的函數?

可寫在等號左邊的函數 int buffer ; int& get_buffer() ; void main() { cout << get_buffer() <<endl ; } int& get_buffer() { return buffer ;}

可寫在等號左邊的函數 const int SIZE = 20 ; int a[SIZE] ; int& getElement(int index) { return a[index] ; } void main() { getElement(5) = 100 ; // a[5] = 100 ; cout << getElement(5) <<endl ; }

安全的陣列 EX: void main() { SafeArray sa(20) ; …… } class SafeArray { int a[20] ; public: int& operator[](int index) { if(index<0 || index >19) {cout<<“out of boundary”<<endl; exit(1); } else {return a[index];} // DIY, 檢查index的範圍 }; void main() { SafeArray sa; sa[5] = 10 ; cout << sa[5] ; EX: void main() { SafeArray sa(20) ; …… }

class Frac完成了沒?