第八章多态性
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//以上两句程序是重载的成员函数声明
void display(); //输出复数 private: //私有数据成员 double real; //复数实部---------类的数据成员 double imag; //复数虚部---------成员函数直接访问 };
21
complex complex::operator +(complex c2) //重载函数的实现 { complex c; c.real=c2.real+real; c.imag=c2.imag+imag; return complex(c.real,c.imag); }
24
程序输出的结果为: c1=(5,4) c2=(2,10) c3=c1-c2=(3,-6) c3=c1+c2=(7,14)
25
面向对象程序设计
运算符重载为类的友元函数
运 算 符 语法形式: 重 friend 函数类型 operator 运算符(形参表) 载
{ }
......
26
面向对象程序设计
面向对象程序设计
动态绑定举例
问题引出:
投石探宠物
36
一个小孩得知邻居院子里养了一 个宠物,当不知道是何物,于是丢一 块石头到邻居院中探明真相。
Class 宠物
{public:
void char *speak{cout<<“zzz”;} …}; Class 猫:public 宠物 {public:
29
complex operator +(complex c1,complex c2) //运算符重载友元函数实现
{ } return complex(c2.real+c1.real, c2.imag+c1.imag);
complex operator -(complex c1,complex c2) //运算符重载友元函数实现
void h();
}; 如果声明:C c1;
c1.g(); 无二义性(同名隐藏)
c1.f(); 具有二义性
面向对象程序设计
二义性问题(二)
class B { public: int b; } class B1 : public B { private: int b1; } class B2 : public B { private: int b2; };
22
complex complex::operator -(complex c2) //重载函数实现 { complex c; c.real=real-c2.real; c.imag=imag-c2.imag; return complex(c.real,c.imag); }
23
void complex::display() { cout<<"("<<real<<","<<imag<<")"<<endl; }
多态的实现
三种办法: – 函数重载 – 运算符重载 – 虚函数
13
面向对象程序设计
运算符重载
运 算 定义: 运算符重载是对已有的运算符赋 符 重 予多重含义. 载
必要性
– C++中预定义的运算符其运算对象只能是 基本数据类型,而不适用于用户自定义 类型(如类)
14
面向对象程序设计
实现机制
将指定的运算表达式转化为对运算 符函数的调用,运算对象转化为运算符 函数的实参。
构造object对象 构造box对象 析构box对象 析构object对象
5
二义性问题(一)
class C: public A, piblic B
{ public: void g();
class A { public: void f(); }; class B { public: void f(); void g(); };
面向对象程序设计
复习 继承与派生 1、概念
2、继承方式
3、类型兼容原则
4、多继承
5、派生类的构造函数和析构函数
6、继承与派生的二义性问题 7、虚基类
1
#include <iostream>
using namespace std;
class object
{private:
int Weight; public: object() {cout<<"构造object对象"<<endl; Weight=0;} //基类构造函数
2、使用虚函数
#include <iostream> using namespace std; // 1、未使用虚函数 class pet {public: void speak() {cout<<“How does a pet speak"<<endl;} }; class Cat: public pet { public: void speak(){ cout<<“miao!miao!"<<endl; } }; class Dog: public pet { public: void speak(){ cout<<“wang!wang!"<<endl; } };
void char *speak{cout<<“miao!miao!”;}
…}; Class 狗:public 宠物 {public: void char *speak{cout<<“miao!miao!”;}
…};
void main()
{宠物 *p;
猫 cat1;
狗 dog1; ….//此处设计程序用户根据输入将猫或 ….//狗对象地址赋给p指针 ….//例如,输入1:p=&cat1,输入2:p=&dog1 p->speak( ); }
class C : public B1,public B2 { public: int f(); private: int d; }
7
class B1 : virtual public B { private: int b1;};
class B2 : virtual public B { private: int b2;};
int GetWeght(){return Weight ;}
void SetWeight(int n){Weight=n;} ~object() {cout<<"析构object对象"<<endl;} };
class box: public object
{private:
int Height, Width; public: box( ){cout<<"构造box对象"<<endl; int Height=Width=0;} //派生类构造函数 int GetHeight(){return Height;} void SetHeght(int n){Height=n;}
重载为友元函数时
1、前面加friend关键字进行说明
2、参数个数=原操作数个数
27
面向对象程序设计
例8-3
运 算 符 重 载
将+、-(双目)重载为复数类的友元 函数。
两个操作数都是复数类的对象。
28
#include<iostream> using namespace std; class complex //复数类声明 { public: //外部接口 complex(double r=0.0,double i=0.0) { real=r; imag=i; } //构造函数 friend complex operator + (complex c1,complex c2); //运算符+重载为友元函数 friend complex operator - (complex c1,complex c2); //运算符-重载为友元函数 void display(); //显示复数的值 private: //私有数据成员 double real; double imag; };
多态性 运算符重载 虚函数 纯虚函数 抽象类
11
面向对象程序设计
多态性的概念
多态性是指发出同样的消息被不同类型的对 象接收时有可能导致完全不同的行为。 同样的消息:调用名称相同的成员函数; 完全不同的行为:函数实现的功能不同。 多态性是面向对象程序设计的重要特征之一。
12
面向对象程序设计
面向对象程序设计
虚函数
虚 函 数
虚函数是动态绑定的基础。
虚函数的语法: virtual 函数返回类型 函数名(参数表) 说明: 1、非静态的成员函数。 2、在类的声明中,在函数原型之前写virtual。 3、virtual 只用来说明类声明中的原型,不能用 在函数实现时。 40
虚函数举例
1、未使用虚函数
运算符重载为类的成员函数
运 算 符 语法形式: 重 函数类型 operator 运算符(形参表) 载 {
...... }
18
面向对象程序设计
重载为类成员函数时
参数个数=原操作数个数-1(后置++、--除外)
原因:当重载为类的成员函数时,自身的数 据可以直接访问,就不需要再放在参数表中进行 传递。
19
int GetWidth(){return Width;}
void SetWidth(int n){Width=n;} ~box(){cout<<"析构box对象"<<endl ; } };
void main() { box *p; p=new box; delete p;
}
面向对象程序设计
输出结果:
1、编译时多态(静态绑定) 指在编译的过程中确定了同名操作的具 体操作对象 2、运行时多态(动态绑定) 指在程序运行过程中才动态地确定操作 所针对的具体对象。
32
面向对象程序设计
两种绑定的优缺点
静态绑定 缺点:不经过重新编译程序就无 法实现静态绑定。 动态绑定 无需重新编译程序就能够实现动 态绑定,不足是时间开销稍大于静态 绑定。
33
面向对象程序设计
静态绑定举例
问题引出:
兔子逃生
34
Class 兔子 {public: ……... void 逃生(老鹰 a){“兔子蹬鹰”;} void 逃生(狼 b){“动若脱兔”;} …………….. };
调用函数时,它们的参数都在编码时设定好的,也 就是当调用“兔子”类的逃生函数时,传入的参数时 “老鹰”还是“狼”的对象,是在编译时确定的。
解决办法:
在第一级继承时就要将共同基类设计为虚基类
派生类C的对象的存储结构示意图:
b
B类成员 B1类成员
b1
b b2 d
B类成员 B2类成员
Байду номын сангаас
C类对象
有二义性: C c; c.b c.B::b
无二义性: c.B1::b c.B2::b
9
面向对象程序设计
第八章 多态性
10
面向对象程序设计
本章主要内容
15
面向对象程序设计
规则和限制
运 算 符 重 载
可以重载C++中除下列运算符外的所有运 算符:. .* :: ?: 只能重载C++语言中已有的运算符,不可 臆造新的。 不能改变操作数个数。
16
面向对象程序设计
运算符重载两种形式
运 算 符 重 载
重载为类成员函数
重载为友元函数
17
面向对象程序设计
面向对象程序设计
例 8.1
运 算 将“+”、“-”运算重载为复数类 符 的成员函数。 重 规则: 载
– 实部和虚部分别相加减。
操作数:
– 两个操作数都是复数类的对象。
20
#include<iostream> using namespace std; class complex //复数类声明 { public: //外部接口 complex(double r=0.0,double i=0.0){real=r;imag=i;} //构造函数 complex operator + (complex c2); //+重载为成员函数 complex operator - (complex c2); //-重载为成员函数
{ return complex(c1.real-c2.real, c1.imag-c2.imag); }
// 其它函数和主函数同例8.1
30
面向对象程序设计
绑 定
多态性是指发出同样的消息被不同 类型的对象接收时有可能导致完全不同的 行为。
这种确定操作的具体对象的过程就是绑定
31
面向对象程序设计
void 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(); }
void display(); //输出复数 private: //私有数据成员 double real; //复数实部---------类的数据成员 double imag; //复数虚部---------成员函数直接访问 };
21
complex complex::operator +(complex c2) //重载函数的实现 { complex c; c.real=c2.real+real; c.imag=c2.imag+imag; return complex(c.real,c.imag); }
24
程序输出的结果为: c1=(5,4) c2=(2,10) c3=c1-c2=(3,-6) c3=c1+c2=(7,14)
25
面向对象程序设计
运算符重载为类的友元函数
运 算 符 语法形式: 重 friend 函数类型 operator 运算符(形参表) 载
{ }
......
26
面向对象程序设计
面向对象程序设计
动态绑定举例
问题引出:
投石探宠物
36
一个小孩得知邻居院子里养了一 个宠物,当不知道是何物,于是丢一 块石头到邻居院中探明真相。
Class 宠物
{public:
void char *speak{cout<<“zzz”;} …}; Class 猫:public 宠物 {public:
29
complex operator +(complex c1,complex c2) //运算符重载友元函数实现
{ } return complex(c2.real+c1.real, c2.imag+c1.imag);
complex operator -(complex c1,complex c2) //运算符重载友元函数实现
void h();
}; 如果声明:C c1;
c1.g(); 无二义性(同名隐藏)
c1.f(); 具有二义性
面向对象程序设计
二义性问题(二)
class B { public: int b; } class B1 : public B { private: int b1; } class B2 : public B { private: int b2; };
22
complex complex::operator -(complex c2) //重载函数实现 { complex c; c.real=real-c2.real; c.imag=imag-c2.imag; return complex(c.real,c.imag); }
23
void complex::display() { cout<<"("<<real<<","<<imag<<")"<<endl; }
多态的实现
三种办法: – 函数重载 – 运算符重载 – 虚函数
13
面向对象程序设计
运算符重载
运 算 定义: 运算符重载是对已有的运算符赋 符 重 予多重含义. 载
必要性
– C++中预定义的运算符其运算对象只能是 基本数据类型,而不适用于用户自定义 类型(如类)
14
面向对象程序设计
实现机制
将指定的运算表达式转化为对运算 符函数的调用,运算对象转化为运算符 函数的实参。
构造object对象 构造box对象 析构box对象 析构object对象
5
二义性问题(一)
class C: public A, piblic B
{ public: void g();
class A { public: void f(); }; class B { public: void f(); void g(); };
面向对象程序设计
复习 继承与派生 1、概念
2、继承方式
3、类型兼容原则
4、多继承
5、派生类的构造函数和析构函数
6、继承与派生的二义性问题 7、虚基类
1
#include <iostream>
using namespace std;
class object
{private:
int Weight; public: object() {cout<<"构造object对象"<<endl; Weight=0;} //基类构造函数
2、使用虚函数
#include <iostream> using namespace std; // 1、未使用虚函数 class pet {public: void speak() {cout<<“How does a pet speak"<<endl;} }; class Cat: public pet { public: void speak(){ cout<<“miao!miao!"<<endl; } }; class Dog: public pet { public: void speak(){ cout<<“wang!wang!"<<endl; } };
void char *speak{cout<<“miao!miao!”;}
…}; Class 狗:public 宠物 {public: void char *speak{cout<<“miao!miao!”;}
…};
void main()
{宠物 *p;
猫 cat1;
狗 dog1; ….//此处设计程序用户根据输入将猫或 ….//狗对象地址赋给p指针 ….//例如,输入1:p=&cat1,输入2:p=&dog1 p->speak( ); }
class C : public B1,public B2 { public: int f(); private: int d; }
7
class B1 : virtual public B { private: int b1;};
class B2 : virtual public B { private: int b2;};
int GetWeght(){return Weight ;}
void SetWeight(int n){Weight=n;} ~object() {cout<<"析构object对象"<<endl;} };
class box: public object
{private:
int Height, Width; public: box( ){cout<<"构造box对象"<<endl; int Height=Width=0;} //派生类构造函数 int GetHeight(){return Height;} void SetHeght(int n){Height=n;}
重载为友元函数时
1、前面加friend关键字进行说明
2、参数个数=原操作数个数
27
面向对象程序设计
例8-3
运 算 符 重 载
将+、-(双目)重载为复数类的友元 函数。
两个操作数都是复数类的对象。
28
#include<iostream> using namespace std; class complex //复数类声明 { public: //外部接口 complex(double r=0.0,double i=0.0) { real=r; imag=i; } //构造函数 friend complex operator + (complex c1,complex c2); //运算符+重载为友元函数 friend complex operator - (complex c1,complex c2); //运算符-重载为友元函数 void display(); //显示复数的值 private: //私有数据成员 double real; double imag; };
多态性 运算符重载 虚函数 纯虚函数 抽象类
11
面向对象程序设计
多态性的概念
多态性是指发出同样的消息被不同类型的对 象接收时有可能导致完全不同的行为。 同样的消息:调用名称相同的成员函数; 完全不同的行为:函数实现的功能不同。 多态性是面向对象程序设计的重要特征之一。
12
面向对象程序设计
面向对象程序设计
虚函数
虚 函 数
虚函数是动态绑定的基础。
虚函数的语法: virtual 函数返回类型 函数名(参数表) 说明: 1、非静态的成员函数。 2、在类的声明中,在函数原型之前写virtual。 3、virtual 只用来说明类声明中的原型,不能用 在函数实现时。 40
虚函数举例
1、未使用虚函数
运算符重载为类的成员函数
运 算 符 语法形式: 重 函数类型 operator 运算符(形参表) 载 {
...... }
18
面向对象程序设计
重载为类成员函数时
参数个数=原操作数个数-1(后置++、--除外)
原因:当重载为类的成员函数时,自身的数 据可以直接访问,就不需要再放在参数表中进行 传递。
19
int GetWidth(){return Width;}
void SetWidth(int n){Width=n;} ~box(){cout<<"析构box对象"<<endl ; } };
void main() { box *p; p=new box; delete p;
}
面向对象程序设计
输出结果:
1、编译时多态(静态绑定) 指在编译的过程中确定了同名操作的具 体操作对象 2、运行时多态(动态绑定) 指在程序运行过程中才动态地确定操作 所针对的具体对象。
32
面向对象程序设计
两种绑定的优缺点
静态绑定 缺点:不经过重新编译程序就无 法实现静态绑定。 动态绑定 无需重新编译程序就能够实现动 态绑定,不足是时间开销稍大于静态 绑定。
33
面向对象程序设计
静态绑定举例
问题引出:
兔子逃生
34
Class 兔子 {public: ……... void 逃生(老鹰 a){“兔子蹬鹰”;} void 逃生(狼 b){“动若脱兔”;} …………….. };
调用函数时,它们的参数都在编码时设定好的,也 就是当调用“兔子”类的逃生函数时,传入的参数时 “老鹰”还是“狼”的对象,是在编译时确定的。
解决办法:
在第一级继承时就要将共同基类设计为虚基类
派生类C的对象的存储结构示意图:
b
B类成员 B1类成员
b1
b b2 d
B类成员 B2类成员
Байду номын сангаас
C类对象
有二义性: C c; c.b c.B::b
无二义性: c.B1::b c.B2::b
9
面向对象程序设计
第八章 多态性
10
面向对象程序设计
本章主要内容
15
面向对象程序设计
规则和限制
运 算 符 重 载
可以重载C++中除下列运算符外的所有运 算符:. .* :: ?: 只能重载C++语言中已有的运算符,不可 臆造新的。 不能改变操作数个数。
16
面向对象程序设计
运算符重载两种形式
运 算 符 重 载
重载为类成员函数
重载为友元函数
17
面向对象程序设计
面向对象程序设计
例 8.1
运 算 将“+”、“-”运算重载为复数类 符 的成员函数。 重 规则: 载
– 实部和虚部分别相加减。
操作数:
– 两个操作数都是复数类的对象。
20
#include<iostream> using namespace std; class complex //复数类声明 { public: //外部接口 complex(double r=0.0,double i=0.0){real=r;imag=i;} //构造函数 complex operator + (complex c2); //+重载为成员函数 complex operator - (complex c2); //-重载为成员函数
{ return complex(c1.real-c2.real, c1.imag-c2.imag); }
// 其它函数和主函数同例8.1
30
面向对象程序设计
绑 定
多态性是指发出同样的消息被不同 类型的对象接收时有可能导致完全不同的 行为。
这种确定操作的具体对象的过程就是绑定
31
面向对象程序设计
void 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(); }