第15讲赋值兼容规则和应用举例 教学目的与要求: 了解与继承有关的综合应用程序设计 掌握赋值兼容规则。 教学内容提要: 1、赋值兼容规则; 2、应用举例; 教学重点:赋值兼容规则。 教学难点:综合应用程序设计。 教学进度:P148P157 教学过程
•教学目的与要求: 了解与继承有关的综合应用程序设计。 掌握赋值兼容规则。 •教学内容提要: 1、 赋值兼容规则; 2、应用举例; •教学重点:赋值兼容规则。 •教学难点:综合应用程序设计。 •教学进度:P148~P157 •教学过程: 第 15 讲 赋值兼容规则和应用举例
15.1赋值兼容原则】 赋值兼容规则是指在公有派生条件下,任何可以使用基类对象 的地方都可以用其派生类的对象替代。 具体的赋值规则如下 (1)可以用派生类的对象给基类对象赋值 比如: class a} lass B: public A void funo o.3; Aa:bb: a /将对象b中所含类A成员的值赋给对象a 说明:赋值的结果是将派生类对象中所含基类成员的 值赋给基类对象中相同的成员。 (2)可以用派生类的对象初始化基类对象的引用; 比如:Bb; /类A、类B的意义同上 A&a=b;/)派生类对象初始化基类对象的引用 (3)可以用派生类对象的地址给基类对象的指针赋值 比如:Bb; 类A、类B的意义同上 Da=&b;∥用派生类对象的地址初始化基类对象的指针
(1)可以用派生类的对象给基类对象赋值; 比如: class A{...}; class B:public A{void fun() {...}}; A a;B b; a =b; //将对象b中所含类A成员的值赋给对象a (2)可以用派生类的对象初始化基类对象的引用; 比如: B b; //类A、类B的意义同上 A &a=b; //用派生类对象初始化基类对象的引用 (3)可以用派生类对象的地址给基类对象的指针赋值。 比如: B b; //类A、类B的意义同上 A *pa =&b; //用派生类对象的地址初始化基类对象的指针 赋值兼容规则是指在公有派生条件下,任何可以使用基类对象 的地方都可以用其派生类的对象替代。 具体的赋值规则如下: 说明:赋值的结果是将派生类对象中所含基类成员的 值赋给基类对象中相同的成员。 15.1 赋值兼容原则】
第2、3种方法建立的基类对象的引用和指针,只能用来访问派生 类对象中从基类继承下来的成员。如果需要用它们来访问派生类 中新增的成员,就必须对它们进行强制类型转换 比如,利用指针pa访问类B对象中的一个成员函数fun0, 就需要采用下述语句:(B*)pa->fun0; 例15-1(赋值兼容原则举例 #includesiostream.h> class a: void fun(a*p); class a public: void display{cout<<"调用类A的函数<<end;} int x: class B: public a
第2、3种方法建立的基类对象的引用和指针,只能用来访问派生 类对象中从基类继承下来的成员。如果需要用它们来访问派生类 中新增的成员,就必须对它们进行强制类型转换。 比如,利用指针pa访问类B对象中的一个成员函数fun(), 就需要采用下述语句: (B*)pa->fun(); #include class A; void fun(A *p); class A { public: void display(){cout<<″调用类A的函数″<<endl;} int x; }; class B:public A { 例 15-1 赋值兼容原则举例
public (续) void display{cout<<"调用类B的函数"<<end;} int class C: public b public: void display{cout<<"调用类C的函数<<end} void main( Bb: C Cx=1; cab
public: void display(){cout<<″调用类B的函数″<<endl;} int y; }; class C: public B { public: void display(){cout<<″调用类C的函数″<<endl;} }; void main() { A a; B b; C c; c.x=1; c.y=2; a=c; b=c; (续)
coutdisplay
coutdisplay(); } a.x=1 b.y=2 a.x=10 b.y=20 调用类A的函数 调用类A的函数 调用类A的函数 (续)
(15.,2应用举例】 15.2.1派生类使用例-公司雇员档案的管理 假设公司雇员分为:雇员( employee)、经理( manager) 工程师( engineer)、高级主管( director)。而且假定只关心这几 类雇员各自的如下一些数据 employee(雇员)类:姓名、年龄、工资; manager(经理)类:姓名、年龄、工资、行政级别; engineer((工程师)类:姓名、年龄、工资、专业、学位; director(高级主管)淡:姓名、年龄、工资、专业、学位、职
15.2.1 派生类使用例 -- 公司雇员档案的管理 假设公司雇员分为:雇员(employee)、经理(manager)、 工程师(engineer)、高级主管(director)。而且假定只关心这几 类雇员各自的如下一些数据: employee(雇员)类: 姓名、年龄、工资; manager(经理)类: 姓名、年龄、工资、行政级别; engineer(工程师)类: 姓名、年龄、工资、专业、学位; director(高级主管)类:姓名、年龄、工资、专业、学位、职务。 【 15.2 应用举例】
#include #include class employee t/ employed6类(类型),将作为其它几个类的基类 short age float salary protected char s name public: employee(short ag, float sa, char* na)i age-ag, salary=sa; name=new charstrlen (na)+1; strcpy(name, na); void print o const( cout<<p <name<<":"; cout<sage<s: cout<<salary<<endl employee delete name j
#include #include class employee { //employee类(类型),将作为其它几个类的基类 short age; float salary; protected: char * name; public: employee (short ag, float sa, char * na){ age=ag; salary=sa; name=new char[strlen(na)+1]; strcpy(name,na); } void print () const{ cout<<" "<<name<<": "; cout<<age<<" : "; cout<<salary<<endl; } ~employee() {delete[ ]name;} };
class manager: public employee/派生类 int level: public: manager(short ag, float sa, char* na, int lev) :employee(ag, sa, na) {/对基类初始化负责 leveller void printoconst employee: printo;/调用基类 print显示“共性”数据 cout < level: <<levek<<endl
class manager:public employee { //派生类 int level; public: manager(short ag, float sa, char* na, int lev) :employee (ag,sa,na) { //对基类初始化负责 level=lev; } void print()const { employee::print(); //调用基类print显示“共性”数据 cout <<" level:"<<level<<endl; } };
/注意:允许派生类中的 print与基类的 print重名,按如下规 定进行处理:对子类而言,不加类名限定时默认为是处理子 类成员,而要访问父类重名成员时,则要通过类名限定 director(short ag, float sa, char*na, char sp, char ad, ptitle p :engineer(ag, sa, na, sp, ad) post=p; void printo i engineer: printo; cout<<“:”<<post<<endl: public
/*注意:允许派生类中的print与基类的print重名,按如下规 定进行处理:对子类而言,不加类名限定时默认为是处理子 类成员,而要访问父类重名成员时,则要通过类名限定*/ class engineer:public employee { char speciality,adegree; public: ... }; enum ptitle {PS,GM,VPS,VGM}; class director:public engineer { ptitle post; public: ... }; director(short ag,float sa,char*na,char sp,char ad,ptitle p) :engineer(ag,sa,na,sp,ad) { post=p; } void print() { engineer::print(); cout<<“:”<<post<<endl; }
void maino[ 主函数 employee emp1(23, 610.5, zhang"), emp2(27,824 zhao manager man1(32, 812.45,li,11) man2(341200.5"cui",7 engineer eng(26, 1420.10,"meng,E, M) director dir(38, 1800.2ZhouC,; empl. printo; emp2 print(; manl printo man2 employee: print0;//调用基类的prnt eng print(; dir. printO
void main() { //主函数 employee emp1(23,610.5,"zhang"), emp2(27,824.75,"zhao"); manager man1(32,812.45,"li",11), man2(34,1200.5,"cui",7); engineer eng(26,1420.10,"meng",'E','M'); director dir(38,1800.2,"zhou",’C’,’D’,GM); emp1.print(); emp2.print(); man1.print(); man2.employee::print(); //调用基类的print eng.print(); dir.print(); }