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

C++ Programming Lecture 15

  • Upload
    taniel

  • View
    22

  • Download
    0

Embed Size (px)

DESCRIPTION

C++ Programming Lecture 15. Wei Liu ( 刘威 ) Dept. of Electronics and Information Eng. Huazhong University of Science and Technology Feb. 2014. The separation of Interfaces and implementations . Interfaces (class definitions) in header file, e.g., myClass.h. - PowerPoint PPT Presentation

Citation preview

Page 1: C++ Programming Lecture 15

C++ ProgrammingLecture 15

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

Huazhong University of Science and TechnologyFeb. 2014

Page 2: C++ Programming Lecture 15

-2-

Single source filee.g., try.cpp

The separation of Interfaces and implementations

Interfaces (class definitions)in header file, e.g., myClass.h

Implementation (member function definitions) in new source file, e.g., myClass.cpp

New source filee.g., myTry.cpp

Page 3: C++ Programming Lecture 15

面向对象的编程 vs. 面向过程的编程

-3-

面向对象的编程 面向过程的编程类的设计 函数的设计

类的调用:类的实例化获得对象对象可以维持自身数据,同时还有方法

函数的调用:主调函数需要维持数据

Page 4: C++ Programming Lecture 15

-4-

Lecture 15 Chapter 17. Classes: A Deeper Look, I

17.1 Introduction 17.2 Time Class Case Study 17.3 Class Scope and Accessing Class Members 17.4 Separating Interface from Implementation 17.5 Access Functions and Utility Functions 17.6 Time Class Case Study: Constructors with Default

Arguments 17.7 Destructors 17.8 When Constructors and Destructors Are Called 17.9 Time Class Case Study: A Subtle Trap Returning a

Reference to a private Data Member 17.10 Default Memberwise Assignment

Page 5: C++ Programming Lecture 15

17.3  Class Scope and Accessing Class Members Class Scope 类的作用域

A class’s data members and member functions belong to that class’s scope. 类的数据成员与成员函数属于该类的作用域

Within a class’s scope, class members are immediately accessible by all of that class’s member functions and can be referenced by name. 类的作用域内,各种成员可以通过名称直接访问

Outside a class’s scope, public class members are referenced through one of the handles on an object—an object name, a reference to an object or a pointer to an object. 类的作用域外,只有 public 的成员可以通过某个对象 ( 形式可以是名称、引用或者指针 ) 来访问

Page 6: C++ Programming Lecture 15

17.3  Class Scope and Accessing Class Members Scopes 作用域

Global namespace scope 全局名称空间作用域 Class scope 类的作用域 Function scope 函数的作用域

Relationships among scopes 作用域的关系 Nonmember functions are defined at global namespace scope. 其他的函数属于全局名称空间的作用域 The same name function-scope variable in member function will

hide the class-scope variable 类似于局部变量与全局变量的关系,在成员函数内定义的同名变量拥有比同名数据成员更高的可见性 We can visit the class-scope variable with the class name

followed by the scope resolution operator (::) 可以通过类的作用域解析符显式访问类的数据成员

Page 7: C++ Programming Lecture 15

17.3  Class Scope and Accessing Class Members Accessing Class Members 访问类的成员

The dot member selection operator (.) is preceded by an object’s name or with a reference to an object to access the object’s members. 逗号成员选择符在某个对象的名称或者引用之后,可以访问该对象的各种成员

The arrow member selection operator (->) is preceded by a pointer to an object to access the object’s members. 箭头成员选择符在某个对象的指针之后,可以访问该对象的各种成员Time a, *b;a.printUniversal();

b->printUniversal();

Page 8: C++ Programming Lecture 15

-8-

创建类的指针、引用的语法与创建基本数据类型的指针、引用的语法类似。

Page 9: C++ Programming Lecture 15

-9-

Lecture 15 Chapter 17. Classes: A Deeper Look, I

17.1 Introduction 17.2 Time Class Case Study 17.3 Class Scope and Accessing Class Members 17.4 Separating Interface from Implementation 17.5 Access Functions and Utility Functions 17.6 Time Class Case Study: Constructors with Default

Arguments 17.7 Destructors 17.8 When Constructors and Destructors Are Called 17.9 Time Class Case Study: A Subtle Trap Returning a

Reference to a private Data Member 17.10 Default Memberwise Assignment

Page 10: C++ Programming Lecture 15

17.4  Separating Interface from Implementation 接口与实现的分离 Separating classes into two files

a header file for the class definition (i.e., the class’s interface) 头文件

a source code file for the class’s member-function definitions (i.e., the class’s implementation) 源文件

Benefits this encourages ISVs(independent software vendors), they

only provide the header files(readable text file) and the object modules(un-readable binary files) 便于软件厂商发布他们的软件产品

Information only internally used in the class will not appear in header files, following the principle of least privilege 体现了软件设计的最小权限原则

Page 11: C++ Programming Lecture 15

-11-

Interfaces (class definitions)in header file, e.g., myClass.h

Implementation (member function definitions) in new source file, e.g., myClass.cpp

source filee.g., myTry.cpp

Separating Interface from Implementation接口与实现的分离

Page 12: C++ Programming Lecture 15

-12-

Lecture 15 Chapter 17. Classes: A Deeper Look, I

17.1 Introduction 17.2 Time Class Case Study 17.3 Class Scope and Accessing Class Members 17.4 Separating Interface from Implementation 17.5 Access Functions and Utility Functions 17.6 Time Class Case Study: Constructors with Default

Arguments 17.7 Destructors 17.8 When Constructors and Destructors Are Called 17.9 Time Class Case Study: A Subtle Trap Returning a

Reference to a private Data Member 17.10 Default Memberwise Assignment

Page 13: C++ Programming Lecture 15

17.5  Access Functions and Utility Functions Member functions 成员函数的作用有几种

Access function 访问函数 Access functions can read or display data. 通常是 public访问权限,提供对类的数据成员的访问,常见的例子有测试条件是真是假,例如 Time 类里面的 isAM() 、 isPM()等

Utility function 工具函数 A utility function is a private member function that

supports the operation of the class’s public member functions. 通常是 private 访问权限,是 public 函数的辅助函数,例如 SalesPerson 类里面的 totalAnnualSales()函数

Page 14: C++ Programming Lecture 15

Chapter 15 Topic 3: What is inside the Class: Creation and Destroy

17.6 Time Class Case Study: Constructors with Default Arguments How default arguments can be used in a constructor.

17.7 Destructors Destructors that perform “termination housekeeping” on

objects before they are destroyed. 17.8 When Constructors and Destructors Are Called

The order in which constructors and destructors are called.

17.10 Default Memberwise Assignment To assign the data members of one object to those of

another by default memberwise assignment

Page 15: C++ Programming Lecture 15

15

17.6  Constructors with Default Arguments Constructors with default argument 默认实参的构造函数

Even if no values are provided in a constructor call, the constructor still initializes the data members 默认实参可以帮助构造函数在无输入时初始化数据成员

A constructor that defaults all its arguments is also a default constructor—i.e., a constructor that can be invoked with no arguments. 对所有实参都有默认值的时候,该构造函数即为默认构造函数,这种函数一个类只能有一个

Page 16: C++ Programming Lecture 15

在类的定义中,构造函数的所有参数都具有默认实参,即为默认构造函数

Page 17: C++ Programming Lecture 15

-17-

构造函数中设置数据成员的工作通过调用setXXX 函数完成,减少重复代码、提高程序的可靠性

构造函数可以调用其他工具函数,但是需要注意数据成员的初始化问题

Page 18: C++ Programming Lecture 15

Chapter 15 Topic 3: What is inside the Class: Creation and Destroy

17.6 Time Class Case Study: Constructors with Default Arguments How default arguments can be used in a constructor.

17.7 Destructors Destructors that perform “termination housekeeping” on

objects before they are destroyed. 17.8 When Constructors and Destructors Are Called

The order in which constructors and destructors are called.

17.10 Default Memberwise Assignment To assign the data members of one object to those of

another by default memberwise assignment

Page 19: C++ Programming Lecture 15

19

17.7  Destructors Destructor 析构函数

The name of the destructor for a class is the tilde character (~) followed by the class name. 函数名即为类名加上 ~

Called implicitly when an object is destroyed. 在对象销毁时被隐式调用 Receives no parameters and returns no value. 析构函数无形式参数、无返回值 A class may have only one destructor. 一个类只能有一个析构函数 A destructor must be public. 析构函数必须是 public 的

Page 20: C++ Programming Lecture 15

20

17.7  Destructors 析构函数 Destructor

The destructor itself does not actually release the object’s memory—it performs termination housekeeping before the object’s memory is reclaimed. 析构函数不能释放对象的内存,但是可以对对象的各种数据成员进行清理

If you do not explicitly provide a destructor, the compiler creates an “empty” destructor. 如果用户没有提供析构函数,编译器将自动创建一个空的析构函数

Page 21: C++ Programming Lecture 15

17.8  When Constructors and Destructors Are Called

Constructors and destructors are called implicitly. 构造函数和析构函数都是被隐式调用的 The order in which these function calls occur depends on

the order in which execution enters and leaves the scopes where the objects are instantiated. The storage classes of objects can alter the order in which destructors are called. 其被调用的顺序与对象的作用域、存储类型、中止方式都有关

Page 22: C++ Programming Lecture 15

22

17.8  When Constructors and Destructors Are Called Issues on scope

Objects in global scope 具有全局作用域的对象 Constructors are called before any other function

(including main) in that file begins execution. The corresponding destructors are called when main terminates. 构造函数在 main() 函数之前调用,析构函数在 main 函数结束时调用

Objects in local scope 具有本地作用域的对象 Constructors and destructors for automatic objects are

called each time execution enters and leaves the scope of the object. 构造函数和析构函数在进入和离开该对象的作用域时调用

Page 23: C++ Programming Lecture 15

23

17.8  When Constructors and Destructors Are Called Issues on storage type

Static object 静态对象 The constructor is called only once, when execution

first reaches the point where the object is defined—the corresponding destructor is called when main terminates or the program calls function exit. 构造函数在碰到该对象时被调用一次,析构函数在 main()结束时调用

Global and static objects are destroyed in the reverse order of their creation. 全局以及静态对象的析构函数调用次序与构造函数相反

Page 24: C++ Programming Lecture 15

24

17.8  When Constructors and Destructors Are Called Issues on termination method

exit() Function exit (keyword) forces a program to

terminate immediately and does not execute the destructors of automatic objects. Exit 函数强迫函数中止,不会调用自动对象析构函数

abort() Function abort (keyword) performs similarly to

function exit without allowing the destructors of any objects to be called. Abort 函数亦强迫函数中止,且不允许调用任何对象的析构函数

Page 25: C++ Programming Lecture 15

-25-

Page 26: C++ Programming Lecture 15

-26-

Page 27: C++ Programming Lecture 15

-27-

Global object

Static objects

Page 28: C++ Programming Lecture 15

Experiment 改进日期类,观察对象的创建与销毁

-28-

date.h

date.cpp

main.cpp

Page 29: C++ Programming Lecture 15

Chapter 15 Topic 3: What is inside the Class: Creation and Destroy

17.6 Time Class Case Study: Constructors with Default Arguments How default arguments can be used in a constructor.

17.7 Destructors Destructors that perform “termination housekeeping” on

objects before they are destroyed. 17.8 When Constructors and Destructors Are Called

The order in which constructors and destructors are called.

17.10 Default Memberwise Assignment To assign the data members of one object to those of

another by default memberwise assignment

Page 30: C++ Programming Lecture 15

30

17.10 Default Memberwise Assignment Memberwise assignment 逐个成员赋值

The assignment operator (=) can be used to assign an object to another object of the same type. 同类型的对象可以通过赋值表达式进行复制

Each data member of the object on the right of the assignment operator is assigned individually to the same data member in the object on the left of the assignment operator. 此时对象的每个数据成员将被赋值给另外一个对象的数据成员(如果数据成员是指针类型,则存在一定风险)

Objects may be passed as function arguments and may be returned from functions using pass-by-value by default. C++ creates a new object and uses a copy constructor to copy the original object’s values into the new object. 对象作为函数形参或者返回值时, C++ 会启用复制构造函数来实现逐个成员的赋值

Page 31: C++ Programming Lecture 15

31

同类型的对象可以通过赋值表达式进行复制 ,此时对象的每个数据成员将被赋值给另外一个对象的数据成员

Page 32: C++ Programming Lecture 15

Chapter 18. Classes: A Deeper Look, II 18.2 const (Constant) Objects and const Member

Functions 18.6 static Class Members

18.3 Composition: Objects as Members of Classes

18.4 friend Functions and friend Classes 18.7 Data Abstraction and Information Hiding

18.5 Using the this Pointer

-32-

Page 33: C++ Programming Lecture 15

18.2 const (Constant) Objects and const Member Functions const object

声明一个对象为常量,本质上与声明常量变量没有区别const Time noon(12,0,0);

const member function 声明一个类的成员函数为常量成员函数,即约定该函数不能修改类的数据成员 prototype 声明void display(int) const ; definition 定义void display(int a) const {

cout << “testing ” << a << endl; }

-33-

Page 34: C++ Programming Lecture 15

A member function is specified as const both in its prototype and in its definition.

Page 35: C++ Programming Lecture 15

A member function is specified as const both in its prototype and in its definition.

Page 36: C++ Programming Lecture 15
Page 37: C++ Programming Lecture 15

const member function 常量成员函数 声明一个类的成员函数为常量成员函数,即约定该函数不能修改类的数据成员 prototype 声明void display(int) const ;

const data members 常量数据成员 声明一个类的数据成员为常量,即约定该数据成员运行期间不允许被修改 这种数据成员的初始化必须通过“成员初始化器”

(member initializers) 来实现 const int increment;

-37-

Page 38: C++ Programming Lecture 15

member initializer member initializer for const data member

常量数据成员的初始化器Increment::Increment(int c, int i) : count( c ), increment( I ) {

... }

在构造函数参数列表之后、构造函数体之前 以 : 开头,以类似函数的形式书写,其中每个数据成员的名称为“函数名”,所需要初始化的值为“函数的参数”

-38-

Page 39: C++ Programming Lecture 15

Member initializers appear between a constructor’s parameter list and the left brace that begins the constructor’s body.

Page 40: C++ Programming Lecture 15
Page 41: C++ Programming Lecture 15

初始化列表 构造函数 + 初始化列表 vs. 构造函数内赋值

初始化列表在构造体之前执行 对内置类型的数据成员没有什么大的区别 对用户自定义类型的数据成员,推荐使用类构造函数初始化列表

下列必须用带有初始化列表的构造函数: 成员类型是没有默认构造函数的类。若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。 const 成员或引用类型的成员。因为 const 对象或引用类型只能初始化,不能对他们赋值。

-41-

Page 42: C++ Programming Lecture 15

Chapter 18. Classes: A Deeper Look, II 18.2 const (Constant) Objects and const Member

Functions 18.6 static Class Members

18.3 Composition: Objects as Members of Classes

18.4 friend Functions and friend Classes 18.7 Data Abstraction and Information Hiding

18.5 Using the this Pointer

-42-

Page 43: C++ Programming Lecture 15

18.6  static Class Members A static data member 静态数据成员

In certain cases, only one copy of a variable should be shared by all objects of a class, such a variable represents “class-wide” information. 静态数据成员是在类的所有对象之间所共享的一个变量的唯一副本

A class’s static members exist even when no objects of that class exist. 静态的数据成员不依赖于任何对象的创建,在程序开始运行后、没有对象被创建时就已经存在

To access a public static class member when no objects of the class exist, prefix the class name and the binary scope resolution operator (::) to the name of the data member. 为了访问类的静态数据成员,需要采用类的作用域声明符 ::

Page 44: C++ Programming Lecture 15

18.6  static Class Members A static data member 静态数据成员的初始化

A fundamental-type static data member is initialized by default to 0. 缺省初始化为 0

If you want a different initial value, a static data member can be initialized once.

A static const data member of int or enum type can be initialized in its declaration in the class definition. 整数类型的静态数据成员可以在类的定义中初始化

All other static data members must be defined at global namespace scope and can be initialized only in those definitions. 其它静态数据成员需要在全局作用域内初始化

If a static data member is an object of a class that provides a default constructor, the static data member need not be initialized because its default constructor will be called.

Page 45: C++ Programming Lecture 15

18.6  static Class Members A static member function 静态的成员函数

To access a private or protected static class member when no objects of the class exist, provide a public static member function and call the function by prefixing its name with the class name and binary scope resolution operator.

为了访问静态的数据成员,需要通过公共的静态成员函数实现 A static member function is a service of the class, not

of a specific object of the class. 静态的成员函数属于整个类,而非某个具体的对象

Page 46: C++ Programming Lecture 15

A member function should be declared static if it does not access non-static data members or non-static member functions of the class.

Page 47: C++ Programming Lecture 15
Page 48: C++ Programming Lecture 15

Experiment 观察常量成员 / 静态成员 / 静态常量数据成员的区别

-48-

class Count{ private: int a_; const int b_; static int c_; static const int d_ = 4;

public: Count(int a = 1, int b = 2): a_(a), b_(b) { }

void display ( void ) { cout << a_ << "," << b_ << "," << c_ << "," << d_ << endl; }

void update ( void ) { a_ += 100; c_ += 100; }};

int Count::c_ = 3;

void create( void );

int main(){ Count countA; countA.display(); countA.update(); countA.display();

Count countB( 11, 22 ); countB.display(); countB.update(); countB.display();

return 0;}

Page 49: C++ Programming Lecture 15

Chapter 18. Classes: A Deeper Look, II 18.2 const (Constant) Objects and const Member

Functions 18.6 static Class Members

18.3 Composition: Objects as Members of Classes

18.4 friend Functions and friend Classes 18.7 Data Abstraction and Information Hiding

18.5 Using the this Pointer

-49-

Page 50: C++ Programming Lecture 15

18.4  friend Functions and friend Classes friend function 友元函数

defined outside that class’s scope, yet has the right to access the non-public (and public) members of the class. 定义在类的范围之外的,可以访问类的非公共数据的函数

Standalone functions, entire classes or member functions of other classes may be declared to be friends of another class. 可以声明为友元的包括函数、类、类的成员函数等

The friendship relation is neither symmetric nor transitive. 友元的关系不是对称的,也不能传递 Friendship is granted, not taken. 友元的关系是以在类的声明中授权方式进行的,函数不能自动获得 Using friend functions can enhance performance.因为减少了数据的传递,友元函数的执行效率要高一些

Page 51: C++ Programming Lecture 15

Friendship: enables a class designer to specify nonmember functions that can access a class’s non-public members

Page 52: C++ Programming Lecture 15

Chapter 18. Classes: A Deeper Look, II 18.2 const (Constant) Objects and const Member

Functions 18.6 static Class Members

18.3 Composition: Objects as Members of Classes

18.4 friend Functions and friend Classes 18.7 Data Abstraction and Information Hiding

18.5 Using the this Pointer

-52-

Page 53: C++ Programming Lecture 15

Data Abstraction and Information Hiding Data Abstraction 数据抽象

C/C++ 内置数据类型: int, double, … 用户自定义的数据类型: class 其实都是抽象数据类型 abstract data type, ADT, 是计算机对现实数据的模拟 ADT 的两个方面:数据表示、数据操作

Information hiding 信息隐藏 类对于用户隐藏实现的细节 类的私有数据不对外开放 友元函数是否破坏了信息隐藏?

类的声明控制了友元的权限 友元和类方法是表达类接口的两种不同的机制 -53-

Page 54: C++ Programming Lecture 15

18.5  Using the this Pointer this 指针

this 指针是 C++ 提供的用于访问对象自己的地址的特殊指针,也是 C++ 的关键词之一 Every object has access to its own address through a

pointer called this. The this pointer is not part of the object itself. 每个对象都内置了一个访问自己地址的 this 指针, this 指针不是对象的数据成员,而是由系统提供的

Objects use the this pointer implicitly or explicitly to reference their data members and member functions. 对象可以通过 this 指针显式或者隐式的访问自己的数据成员与成员函数

Page 55: C++ Programming Lecture 15
Page 56: C++ Programming Lecture 15

18.5  Using the this Pointer (cont.) Another use of the this pointer is to enable

cascaded member-function calls this 指针的重要用途之一是实现级联式的函数调用

invoking multiple functions in the same statement

Page 57: C++ Programming Lecture 15

57

The dot operator (.) associates from left to right, so first evaluates t.setHour(18), then returns a reference to object t as the value of this function call.

The remaining expression is then interpreted as t.setMinute( 30 ).setSecond( 22 );

The t.setMinute( 30 ) call executes and returns a reference to the object t.

The remaining expression is interpreted as t.setSecond( 22 );

Page 58: C++ Programming Lecture 15

Returning *pointer to get the reference获得当前对象的引用

Page 59: C++ Programming Lecture 15

Experiment 运行 Time 类,观察 this 指针的使用

Page 60: C++ Programming Lecture 15

作业 18.6 修改 Date 类 18.9 修改 Time 类 19.8 实现复数 Complex 类

-60-

Page 61: C++ Programming Lecture 15

谢谢!刘威 副教授

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