9.继承和多态 应用和示例
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Point3d 子对象 Vertex子对象
Vertex3d obj3; //指针赋值 Point3d *p3d=&obj3; Vertex *pv=&obj3; //涉及指针偏移
赋值相容规则:
//对象赋值 obj1=obj3; obj2=obj3;
多重继承的内存布局
多重继承中数据成员的Βιβλιοθήκη Baidu义性
class base1{ protected: int member; public: base1(){ //… } }; class base2{ protected: int member; public: base2(){ //… } }; class derived: public base1, public base2{ private: int total; public: derived(){ //… } void func(){ member=0; //二义性 } }; int member 来自base1 int member 来自base2 int total derived对象布局
赋值相同规则
通过公有继承,派生类的对象可以当作基类使用
class Point2d{ public: void show(); Point3d obj3d; Point2d obj2d; protected: float x,y; float x float x }; float y float y class Point3d: public Point2d{ public: void show(); float z private: float z; }; void main(){ 派生类对象赋值给基类对象 Point2d obj2d; Point3d obj3d; 向上映射、对象切片 obj2d=obj3d; //对象赋值 obj2d.show(); //调用Point2d::show() }
构造函数和析构函数的调用顺序 访问权限的理解
继承的内存布局
对比:对象成员
class Point2d{ public: Point2d(){ //… } //…… protected: float x,y; }; class Point3d: { public: Point3d():point(){ //… } //…… private: Point2d point; float z; }; Point2d obj1; float x float y Point3d obj2; float x float y float z point 对象成员
base1::member=0; base2::member=0;
多重继承的内存布局
虚拟基类之前的内存布局
class base{ int b2 int b1 protected: int b; }; base1的内存布局 base2的内存布局 class base1: public base{ protected: int b1; int b 二义性 }; class base2: public base{ int b1 protected: int b2; int b }; class derived: public base1, public base2{ int b2 float d; float d public: int fun(); }; derived的内存布局 不能把derived对象当base对象使用 int b int b
继承的使用
Checking类继承Saving类
Saving accNumber balance Saving() Withdraw() Deposit() Display() 储蓄账户 Checking remittance Checking() Withdraw() SetRemit() Consume() 结算账户
赋值相同规则
通过公有继承,派生类指针可以赋给基类指针
class Point2d{ Point3d obj3d; Point2d obj2d; public: void show(); p3d p2d protected: float x float x p2d float x,y; float y float y }; class Point3d: public Point2d{ float z public: void show(); private: float z; //指针赋值 }; Point2d *p2d=&obj2d; void main(){ Point3d *p3d=&obj3d; Point2d obj2d; p2d=p3d; Point3d obj3d; p2d->show(); 调用Point2d::show() }
多重继承的内存布局
虚拟基类的内存布局
通过指针指向共享的虚拟基类 int b1 int b2 class base{ base* p base* p protected: int b; }; int b int b class base1: virtual public base{ base1的内存布局 base2的内存布局 protected: int b1; }; int b1 class base2: virtual public base{ protected: int b2; base* p }; int b2 class derived: public base1, public base2{ float d; base* p public: int fun(); derived的内存布局 float d }; 可以把derived对象当base对象使用 int b
继承的使用
从现实中捕获一般-特殊关系
class Automobile{ public: Automobile(); void start(); void stop(); void speedup(); void speeddown(); protected: char* brand; float price; float speed; }; class Car: public Automobile{ public: Car(); void absstop(); private: float gas_comsume; }; class Jeep: public Automobile{ public: Jeep(); void climb(); private: int drive; }; class Truck: public Automobile{ public: Truck(); void transport(); private: float load; }; Automobile
多重继承的内存布局
class Point2d{ public: //… Point2d Vertex protected: float x,y; }; class Point3d: public Point2d{ Point3d public: //… protected: float z; }; Vertex3d class Vertex{ public: //… protected: Vertex* next; }; class Vertex3d: public Point3d, public Vertex{ public: //… protected: float mumble; };
继承和多态 应用和示例
闫哲
yzh@cs.pku.edu.cn 2005年6月24日
内容
继承的内存布局 赋值相容规则 继承举例 虚函数实现原理 多态性举例 设计模式
继承的内存布局
通过继承,派生类中包含基类成员
class Point2d{ public: Point2d(){ //… } //…… protected: private: float x,y; }; class Point3d: public Point2d{ public: Point3d():Point2d(){ //… } //…… private: float z; }; Point2d obj1; float x float y Point3d obj2; float x float y float z 基类成员
继承的使用
class Saving{ protected: int accNumber; float balance; public: Saving(int accNo,float bal=0); void Withdraw(float bal); void Deposit(float bal); void Display(); }; class Checking: public Saving{ private: int remittance; public: Checking(int accNo,float bal=0); void Withdraw(float bal); void setRemit(int rem); void Consume(float price, float add); }; #include<iostream.h> //Saving的实现… Checking::Checking(int accNo, float bal=0): Saving(accNo,bal){} void Checking::Withdraw(float bal){ float tmp;//根据remit计算 if(tmp<balance&&tmp>0) balance-=tmp; } void Checking::setRemit(int rem){ remittance=remit; } Void Checking::Consume(float price, float add=0){ float tmp=price+add; if(tmp<balance && tmp>0) balance-=tmp; }
通过多重继承,派生类中包含各基类成员
多重继承的内存布局
Point2d 子对象 float x float y float z Point3d obj1; Vertex* next Vertex obj2; Point2d 子对象 float x float y float z
Vertex* next float mumble
void Checking::Withdraw(float bal){ float tmp; //… 根据remit值计算tmp if(tmp<balance && tmp>0) balance-=tmp;} void Checking::Deposit(float bal){ if(bal>0) balance+=bal; } void Checking::Display(){ cout<<“Saving Account[”<<accNo<<“]:” <<balance<<endl; } void Checking::SetRemit(int rem){ remittance=rem; } void Checking::Consume(float price, float add=0){ float tmp=price+add; if(tmp<balance && tmp>0) balance-=tmp; }
在银行业务中,有储蓄(Saving)账户和结算(Checking)账户之分,两个类的设计:
结算账户
继承的使用
//类的定义省略 #include<iostream.h> Saving::Saving(int accNo,float bal=0){ accNumber=accNo; balance=bal; } void Saving::Withdraw(float bal){ if(bal<balance && bal>0) balance-=bal; } void Saving::Deposit(float bal){ if(bal>0) balance+=bal; } void Saving::Display(){ cout<<“Saving Account[”<<accNo <<“]:”<<balance<<endl; } Checking::Checking(int accNo, float bal=0){ accNumber=accNo; balance=bal; }
Car
Jeep
Truck
继承的使用
从相似的类中提取共同的特征,形成类层次
Saving accNumber balance Saving() Withdraw() Deposit() Display() 储蓄账户 Checking accNumber balance remittance Checking() Withdraw() Deposit() Display() SetRemit() Consume()