向刍回 1派生类具有基类的所有 成员。 2.派生类的构造函数自动 执行基类的构造函数 且基类的构造函数先执 行。基类构造函数的参 数由派生类传递 3.派生类中可对已有的成 员进行重新定义。 4可定义多重派生类。且 可利用虚基类使派生类 只保持一个基类的成员 拷贝
1. 派生类具有基类的所有 成员。 2. 派生类的构造函数自动 执行基类的构造函数, 且基类的构造函数先执 行。基类构造函数的参 数由派生类传递。 3. 派生类中可对已有的成 员进行重新定义。 4.可定义多重派生类。且 可利用虚基类使派生类 只保持一个基类的成员 拷贝
南8信多态的概念 (++ C+十 4+十 ++ 第十讲虛函数与多态性 8.1多态的概念 8.2虚函数 态
第十讲 虚函数与多态性 8.1 多态的概念 8.2 虚函数 §8.1 多态的概念
信多态的概念 (++ C+十 4+十 ++ 什么是多态性 指在一般类中定义的操作在被继承类继 承后可以有不同的表现形式。 例如:图形的求面积 类: shape 操作:求面积 类:椭圆 类:长方形 操作:求面积操作:求面积 解决的方法:用虚函数实现动态联编
§8.1 多态的概念 什么是多态性 指在一般类中定义的操作在被继承类继 承后可以有不同的表现形式。 例如:图形的求面积 类:shape 操作:求面积 类:椭圆 操作:求面积 类:长方形 操作:求面积 解决的方法:用虚函数实现动态联编
信多态的概念 (++ 例1:没有用多态性的例题 #include class A 结果:AA public void print(i cout print();访问基类函数 p=&b;,p→ print();∥希望访问派生类函数
§8.1 多态的概念 例1:没有用多态性的例题 #include class A { public: void print( ) { cout print( ); //访问基类函数 p= &b; p->print( ); //希望访问派生类函数 } 结果:AA
8.2虚函数 (++ C+十 4+十 ++ 虚函数的定义方法 在基类中,在要被定义成虚函数的函数前加关键字 virtual 例如: virtual void print() 注意:1.关键字是 virtual 2.放在最前面,函数的类型不能忘, 如 virtual void print(():中的void 3.可只在基类中的函数加 virtual,在派生类中不加 但为了便于阅读可在所有要声明为虚函数的 前面都加 virtual 4.只需要在类定义文件,即头文件中的虚函数加 virtual,在cpp文件中就不要再加 virtual
§8.2 虚函数 虚函数的定义方法 在基类中,在要被定义成虚函数的函数前加关键字 virtual 例如: virtual void print( ); 注意:1. 关键字是 virtual 2. 放在最前面,函数的类型不能忘, 如 virtual void print( ): 中的 void 3. 可只在基类中的函数加 virtual,在派生类中不加, 但为了便于阅读,可在所有要声明为虚函数的 前面都加 virtual 4. 只需要在类定义文件,即头文件中的虚函数加 virtual, 在 cpp 文件中就不要再加 virtual
82虚函数 (++ C+十 4+十 ++ 例2:用多态性解决例1中的问题 #include class base public virtual void print(){cout<“base”;}};∥定义了虚函数 P的/n、 public base{/定义派生类 class first void print(){cout<<“frst”;}};∥重新定义 print(() class second: public base{/定义派生类 public void print(){cout<<" second";}};∥重新定义 print()
§8.2 虚函数 例2:用多态性解决例1中的问题 #include class base { public: virtual void print( ) { cout << “base ”; } }; //定义了虚函数 class first:public base { //定义派生类 public: void print( ) { cout << “ first ”; } }; //重新定义print( ) class second:public base { //定义派生类 public: void print( ) { cout << " second "; } }; //重新定义print( )
82虚函数 (++ C+十 4+十 ++ void main(i base ob1,*p;∥定义基类的对象 first ob2;定义派生类的对象 second ob3;定义派生类的对象 p=&obl;/p指向基类对象obl p> print(;∥调基类成员函数 p=&ob2;∥1p指向子类对象ob2 p-> print();∥动态联编,调子类成员函数 p=&ob3;∥p指向子类对象ob3 p-> print();∥动态联编,调子类成员函数 结果:base first second
§8.2 虚函数 void main( ) { base ob1, *p; //定义基类的对象 first ob2; //定义派生类的对象 second ob3; //定义派生类的对象 p= &ob1; //p 指向基类对象 ob1 p->print( ); // 调基类成员函数 p= &ob2; // p 指向子类对象 ob2 p->print( ); // 动态联编, 调子类成员函数 p= &ob3; // p 指向子类对象 ob3 p->print( ); // 动态联编, 调子类成员函数 } 结果:base first second
82虚函数 例2的相关内容总结 1.基类中的虚函数是由 virtual定义的 virtual void printo) 2.在定义了虚函数之后,只要定义一个基类的指针,就可 以调用子类的函数 p=&ob2;∥p指向子类对象ob2 p-> print();∥/动态联编,调子类成员函数 3.要实现动态联编,子类中的函数必需与基类的函数形式 致,若在子类中对虚函数的形式进行了改变,则子类中 的函数将失去多态性(详细见下例)
§8.2 虚函数 例2的相关内容总结 1. 基类中的虚函数是由virtual 定义的: virtual void print( ); 2. 在定义了虚函数之后, 只要定义一个基类的指针,就可 以调用子类的函数: p= &ob2; // p 指向子类对象 ob2 p->print( ); // 动态联编, 调子类成员函数 3. 要实现动态联编,子类中的函数必需与基类的函数形式 一致,若在子类中对虚函数的形式进行了改变,则子类中 的函数将失去多态性(详细见下例)
毫看2函数 (++ C+十 4+十 ++ 例3.虚函数重载讨论 #includesiostream. h> class base public virtual void fl(){cout<<" fl function of base n";}∥定义虚函数 virtual void fa2(){cout<"f2 function of base n";}/定义虚函数 void B30 cout<< "f3 function of base n") ∥定义一般虚函数 } class derive: public base i public void fl(i cout<< "fl function of derive n 重新定义虚函数 void f2(intx){cout<<"f2 function of derive n";}∥重新定义虚函数, ∥)由于形式改变,失去 ∥函数功能 void fe3(){cout<<"f3 function of derive n",}∥重新定义一般函数
§8.2 虚函数 例3. 虚函数重载讨论 #include class base { public: virtual void f1( ) { cout << "f1 function of base \n "; } //定义虚函数 virtual void f2( ) { cout << " f2 function of base \n "; } //定义虚函数 void f3( ) { cout << " f3 function of base \n "; } //定义一般虚函数 }; class derive: public base { public: void f1( ) { cout << " f1 function of derive \n "; } //重新定义虚函数 void f2(int x ) {cout << " f2 function of derive \n "; } //重新定义虚函数, //由于形式改变,失去 //虚函数功能 void f3( ) { cout << " f3 function of derive \n "; } //重新定义一般函数 };
82虚函数 (++ C+十 4+十 ++ void main() base ob1,*p;∥定义基类对象 结果: fl function of base derive ob2;定义派生类对象 f2 function of base p=&obl f3 function of base p>f1();∥调基类函数 fl function of derive p>2();∥调基类函数 f2 function of base p>B3();∥调基类函数 f3 function of base p=&ob2 p>们1();∥调子类函数,多态性 p>P2();∥调基类函数,由于P的形式改变 p>B3();∥调基类函数,由于没有定义为虚函数
§8.2 虚函数 void main( ) { base ob1, *p; //定义基类对象 derive ob2; //定义派生类对象 p=&ob1; p->f1( ); //调基类函数 p->f2( ); //调基类函数 p->f3( ); //调基类函数 p=&ob2; p->f1( ); //调子类函数,多态性 p->f2( ); //调基类函数,由于f2的形式改变 p->f3( ); //调基类函数,由于没有定义为虚函数 } 结果: f1 function of base f2 function of base f3 function of base f1 function of derive f2 function of base f3 function of base