47
C++ Programming Lecture 16 Wei Liu ( 刘刘 ) Dept. of Electronics and Information Eng. Huazhong University of Science and Technology Feb. 2014

C++ Programming Lecture 16

  • Upload
    edda

  • View
    55

  • Download
    0

Embed Size (px)

DESCRIPTION

C++ Programming Lecture 16. Wei Liu ( 刘威 ) Dept. of Electronics and Information Eng. Huazhong University of Science and Technology Feb. 2014. Lecture 16. Chapter 19. Operator Overloading 19.1 Introduction 19.2 Fundamentals of Operator Overloading 19.3 Restrictions on Operator Overloading - PowerPoint PPT Presentation

Citation preview

Page 1: C++ Programming Lecture 16

C++ ProgrammingLecture 16

Wei Liu ( 刘威 )Dept. of Electronics and Information Eng.

Huazhong University of Science and TechnologyFeb. 2014

Page 2: C++ Programming Lecture 16

Lecture 16 Chapter 19. Operator Overloading

19.1 Introduction 19.2 Fundamentals of Operator Overloading 19.3 Restrictions on Operator Overloading 19.4 Operator Functions as Class Members vs. Global Functions 19.5 Overloading Stream Insertion and Stream Extraction Operators 19.6 Overloading Unary Operators 19.7 Overloading Binary Operators 19.8 Dynamic Memory Management 19.9 Case Study: Array Class 19.10 Converting between Types 19.11 Case Study: String Class 19.12 Overloading ++ and -- 19.13 Case Study: A Date Class 19.14 Standard Library Class string 19.15 explicit Constructors

-2-

Page 3: C++ Programming Lecture 16

Chapter 19. Operator Overloading 运算符重载

对特定的类定义相应的运算符的功能 通过函数来实现

学习要点 实现对象运算的成员函数如何设计? 运算符重载的成员函数如何定义?如何调用? 运算符重载的全局函数如何定义?如何调用?

-3-

Page 4: C++ Programming Lecture 16

-4-

show 函数输出“ xx:xx” 的字符信息strstream 是 C++ 标准 string 流处理类,该类可以接受流式输入,也可以转换为特定类型的对象输出

案例讨论:时间类

operator1.cpp

Page 5: C++ Programming Lecture 16

-5-

案例讨论:时间类

设计 sum 函数,完成两个 time 对象相加的功能:result = this + more对象 more 是函数 sum 的一个参数对象 result 是由函数 sum 创建的临时对象

形参是对象的引用,降低传递的开销函数 sum 是 const 表示不会修改对象this

operator1.cpp

Page 6: C++ Programming Lecture 16

-6-

案例讨论:时间类operator1.cpp

Page 7: C++ Programming Lecture 16

-7-

案例讨论:时间类

该 sum 函数返回值只能设为 Time 对象,而不能是对象的引用。 Why ?operator2.cpp

operator1.cpp

Page 8: C++ Programming Lecture 16

-8-

案例讨论:时间类

该 sum 函数,可以改造成等效的运算符重载函数 operator+

operator1.cpp

operator3.cpp

Page 9: C++ Programming Lecture 16

-9-

案例讨论:时间类operator+ 可以显式的以函数调用的形式调用 : a.operator+(b)

operator+ 也可以用表达式的形式调用 : a+b

operator+ 的函数调用方式参考运算符 + 的结合性来展开

受限于函数调用关系,对象 a 的成员函数 operator+ 只能支持 a + b 形式的函数调用,不能支持 b + a 形式的函数调用如果希望表达式的第一个操作数可以不是对象,则需要采用全局函数的方法

operator3.cpp

Page 10: C++ Programming Lecture 16

-10-

案例讨论:时间类

Time * int_k 的表达式用 Time 类的成员函数重载operator* 来实现,该函数的参数是 int_k

int_k * Time 的表达式用 Time 类的全局友元函数重载operator* 来实现,该函数的参数分别是 int_k , Time_t

operator4.cpp

Page 11: C++ Programming Lecture 16

-11-

案例讨论:时间类Time 成员函数重载运算符,支持 Time * int_k 的表达式Time 的全局友元函数重载运算符,支持 int_k * Time 的表达式

operator4.cpp

Page 12: C++ Programming Lecture 16

小结 运算符重载的学习要点

实现对象运算的成员函数如何设计? 返回值可以是一个对象。函数调用完毕后,该对象将以函数返回值的形式复制给主调函数的接受对象。 返回值可以是一个引用。但是该引用必须能在函数调用完毕后有意义,即不能使“悬挂引用”

运算符重载的成员函数如何定义?如何调用? 二元运算符重载时,该函数只需要接收另一个对象 more 作为参数 调用该函数时, this 对象出现在运算符左边, more 对象出现在右边

运算符重载的全局函数如何定义?如何调用? 二元运算符重载时,该函数需要接收两个对象作为参数 调用该函数时,第一个实参在运算符左边,第二个实参在右边

-12-

Page 13: C++ Programming Lecture 16

Experiment 改写 Time 类,重载运算符,支持时间的相减运算

1. 采用成员函数 2. 采用全局友元函数 3. 采用全局非友元函数

Page 14: C++ Programming Lecture 16

Lecture 16 Chapter 19. Operator Overloading

19.1 Introduction 19.2 Fundamentals of Operator Overloading 19.3 Restrictions on Operator Overloading 19.4 Operator Functions as Class Members vs. Global Functions 19.5 Overloading Stream Insertion and Stream Extraction Operators 19.6 Overloading Unary Operators 19.7 Overloading Binary Operators 19.8 Dynamic Memory Management 19.9 Case Study: Array Class 19.10 Converting between Types 19.11 Case Study: String Class 19.12 Overloading ++ and -- 19.13 Case Study: A Date Class 19.14 Standard Library Class string 19.15 explicit Constructors

-14-

Page 15: C++ Programming Lecture 16

19.2 Fundamentals Three exceptions in operator overloading 要对类的对象使用运算符,就需要运算符重载,三种例外情况是:

The assignment operator (=) may be used with every class to perform memberwise assignment of the class’s data members. 赋值运算符无需重载

The address (&) and comma (,) operators may also be used with objects of any class without overloading. 取地址和逗号运算符无需重载

-15-

Page 16: C++ Programming Lecture 16

19.3  Restrictions Restrictions

The precedence of an operator cannot be changed 重载不能改变运算符的优先级 The associativity of an operator (i.e., whether the operator

is applied right-to-left or left-to-right) cannot be changed 重载不能改变运算符的结合律 It isn’t possible to change the “arity” of an operator 重载不能改变运算符的元数 相关的运算符不会自动重载

= vs. += == vs. !=

-16-

Page 17: C++ Programming Lecture 16

19.4 Operator Functions as Class Members vs. Global Functions

Class Members 成员函数 Global Functions 全局函数参数调用 用 this 指针隐式的获得一个类的

对象的实参,即二元运算符的第一个操作数

用显式的方式获得二元运算符的两个操作数

函数调用 最左侧的操作数必须是该运算符所属类的对象

如果左操作数必须是其它类的对象或者基本类型对象 ( 例如 int, double) ,则运算符函数必须实现为全局函数如果必须直接访问 private 或者protected 成员,则该函数必须是该类的友元函数

重载限制 必须重载为类的成员的运算符:( ) [ ] -> = += -=

下列运算符通常重载为全局函数: << >>

-17-

Page 18: C++ Programming Lecture 16

Lecture 16 Chapter 19. Operator Overloading

19.1 Introduction 19.2 Fundamentals of Operator Overloading 19.3 Restrictions on Operator Overloading 19.4 Operator Functions as Class Members vs. Global Functions 19.5 Overloading Stream Insertion and Stream Extraction Operators 19.6 Overloading Unary Operators 19.7 Overloading Binary Operators 19.8 Dynamic Memory Management 19.9 Case Study: Array Class 19.10 Converting between Types 19.11 Case Study: String Class 19.12 Overloading ++ and -- 19.13 Case Study: A Date Class 19.14 Standard Library Class string 19.15 explicit Constructors

-18-

Page 19: C++ Programming Lecture 16

11.8  Dynamic Memory Management dynamic memory management 动态内存分配

C++ enables you to control the allocation and deallocation. performed with operator new and delete.

new operator 获得动态内存 to dynamically allocate (i.e., reserve) the exact amount of

memory required to hold an object or array at execution time. The object or array is created in the free store (also called the

heap)—a region of memory assigned to each program for storing dynamically allocated objects.

delete operator 释放动态内存 You can return memory to the free store by using the delete

operator to deallocate it. -19-

Page 20: C++ Programming Lecture 16

-20-

案例讨论:时间类operator6.cpp

在 Time 构造和析构函数中增加打印信息

可以观察到表达式运算过程中临时对象的创建和销毁

Page 21: C++ Programming Lecture 16

-21-

operator7.cpp

采用 new[ ] 动态创建 Time 数组时,只能采用默认构造函数

可以观察到表达式运算过采用new[ ] 动态创建的对象数组,需要用 delete[ ] 释放相应的内存

案例讨论:时间类

Page 22: C++ Programming Lecture 16

11.9  Case Study: Array Class In this example, we create a powerful Array class:

Performs range checking. 支持下标边界检查 Allows one array object to be as-signed to another with the

assignment operator. 支持数组直接赋值 Objects know their own size. 数组知道自己的大小 Input or output entire arrays with the stream extraction and

stream insertion operators, respectively. 数组可以整体输入和输出 Can compare Arrays with the equality operators == and !=. 数组可以整体进行比较

C++ Standard Library class template vector provides many of these capabilities as well.

-22-

Page 23: C++ Programming Lecture 16
Page 24: C++ Programming Lecture 16

uses new to obtain the memory for the internal pointer-based representation of this array and assigns the pointer returned by new to data member ptr

uses delete [] to release the memory allocated dynamically by new in the constructor.

Page 25: C++ Programming Lecture 16

When the compiler sees the expression integers1 = integers2, the compiler invokes member function operator= with the call integers1.operator=(integers2)

returning the current object (i.e., *this as a constant reference; this enables cascaded Array assignments such as x = y = z

When the compiler sees the expression integers1 == integers2, the compiler invokes member function operator== with the callintegers1.operator==(integers2 )

Page 26: C++ Programming Lecture 16

When the compiler sees the expression integers1[5] it invokes the appropriate overloaded operator[] member function by gener-ating the call

integers1.operator[]( 5 )

If the subscript is in range, the const version of operator[] returns a copy of the appropriate element of the array.

If the subscript is in range, the non-const version of operator[] returns the appropriate array element as a reference so that it may be used as a modifiable lvalue.

Page 27: C++ Programming Lecture 16

These stream insertion and stream extraction operator functions cannot be members of class Array, because the Array object is always mentioned on the right side of the stream insertion operator and the stream extraction operator.

Page 28: C++ Programming Lecture 16
Page 29: C++ Programming Lecture 16
Page 30: C++ Programming Lecture 16

Lecture 16 Chapter 19. Operator Overloading

19.1 Introduction 19.2 Fundamentals of Operator Overloading 19.3 Restrictions on Operator Overloading 19.4 Operator Functions as Class Members vs. Global Functions 19.5 Overloading Stream Insertion and Stream Extraction Operators 19.6 Overloading Unary Operators 19.7 Overloading Binary Operators 19.8 Dynamic Memory Management 19.9 Case Study: Array Class 19.10 Converting between Types 19.11 Case Study: String Class 19.12 Overloading ++ and -- 19.13 Case Study: A Date Class 19.14 Standard Library Class string 19.15 explicit Constructors

-30-

Page 31: C++ Programming Lecture 16

19.14 Standard Library Class string

-31-

Page 32: C++ Programming Lecture 16

-32-

Page 33: C++ Programming Lecture 16

-33-

Page 34: C++ Programming Lecture 16

-34-

Page 35: C++ Programming Lecture 16

-35-

Page 36: C++ Programming Lecture 16

Lecture 16 Chapter 20. Object-Oriented Programming: Inheritance

20.1 Introduction 20.2 Base Classes and Derived Classes 20.3 protected Members 20.4 Relationship between Base Classes and Derived Classes 20.5 Constructors and Destructors in Derived Classes 20.6 public, protected and private Inheritance 20.7 Software Engineering with Inheritance

-36-

Page 37: C++ Programming Lecture 16

20.1 Introduction Inheritance is a form of software reuse in which you create a

class that absorbs an existing class’s data and behaviors and enhances them with new capabilities.

You can designate that the new class should inherit the members of an existing class.

继承是一种软件重用的方式。如果现有类可以描述事物的现有数据和行为,通过继承来获得和增强类的能力 This existing class is called the base class, and the new class is

referred to as the derived class. 现有的类被称为基类,从基类继承出来的类被称为派生类

-37-

Page 38: C++ Programming Lecture 16

-38-

Student

Graduate

Master Ph.D

学生

研究生

硕士研究生 博士研究生

Student

+ int id;+ string name;+ float score;- char gender;

+ Student()+ display() Graduate

+ int id;+ string name;+ float score;- char gender;- float pay;

+ Graduate()+ display()

Page 39: C++ Programming Lecture 16

Class of student : student.h

-39-

Protected 表示数据成员可以被继承

Priviate 表示数据成员在继承时将被隐藏,不能直接访问

Page 40: C++ Programming Lecture 16

Class of student : studend.cpp

-40-

Page 41: C++ Programming Lecture 16

Class of graduate: graduate.h

-41-

表示继承 Student 类的所有公共属性

派生类可以创建新的数据成员、新的成员函数、改写基类的成员函数基类的数据成员和成员函数都自动地可以被派生类访问

Page 42: C++ Programming Lecture 16

Class of graduate: graduate.cpp

-42-

派生类访问基类的成员函数需要用域说明符 ::

Page 43: C++ Programming Lecture 16

Using inheritance

-43-

Page 44: C++ Programming Lecture 16

Advanced programming (1) Default arguments in constructor

Calling parent constructor in child class

-44-派生类不必使用基类的全部数据成员

Page 45: C++ Programming Lecture 16

Advanced programming (2) Visiting protected / private data members of

parent class

-45-

派生类不能访问基类的私有数据成员

派生类可以通过访问基类的公共成员函数来间接获取私有数据成员的值

Page 46: C++ Programming Lecture 16

作业 19.9 实现超大整数 HugeInt 类的运算符重载 设计一个基类 Event 和两个派生类

Meeting , Lecture ,编写测试程序验证其功能 Event 类描述时间、地点、事件; Meeting 类描述时间、地点、会议议程、参会人员; Lecture 类描述时间、教室地点、授课教师、课程名称、授课内容

预习多态,结合上面的题目,编写基类和派生类的display() 函数,展示多态性

-46-

Page 47: C++ Programming Lecture 16

谢谢!刘威 副教授

互联网技术与工程研究中心华中科技大学电子与信息工程系电话: 13986224922Email: [email protected] 网址: http://itec.hust.edu.cn