虚函数&多态

来源:互联网 发布:38号车评中心 知乎 编辑:程序博客网 时间:2024/05/17 15:16

一、虚函数和多态

·什么是虚函数?

类的成员函数前加上virtual关键字,则这个成员函数就是虚函数。

·什么是虚函数重写?
        当在子类中定义了一个与父类完全相同的(名字相同,参数相同)的虚函数时,则称子类的这个函数重写(也称覆盖)了父类的这个虚函数。

·什么是多态?

       使用基类的指针或引用调用重写的虚函数时,当指向父类调用的就是父类的虚函数,指向子类调用的就是子类的虚函数。



注意:
1、虚函数与虚继承无关,只是关键字相同。虚函数是用来实现多态的,虚继承是解决菱形继承所引发的二义性和数据冗余的。


2、虚函数在子类中重写时可以不用加virtual关键字,虚函数声明和定义分离时,声明加virtual关键字,定义不加。


3、构成多态的条件:
a:虚函数重写

b:有父类的指针和引用


4、虚函数的调用原则:

        b:不构成多态,跟类型有关  

a:构成多态,跟对象有关

5、不要在构造函数和析构函数里面调用虚函数,因为对象是不完整的,可能发生未定义的行为。

示例:

class A{A(){virtual f();}~A(){virtual f();}};class B:public A{B();~B();};int main(){B b;}
如上代码,要构造一个B类的对象b,因为B是A的子类,B要继承A所以先要构造A。又因为B的构造函数是合成的,要构造A,要去A类内调A的构造函数。但A内又调用了虚函数,A是父类,隐含一个this指针。当this指针指向f(),若f()这个虚函数重写了,则构成多态,因为此时实在构造b,对象时B类,则多态调用B的f(),但是B的f()等还没来得及定义!


同理,析构b时,先析构子类的内容,再析构父类的内容,若析构父类时调用了一个虚函数f(),则有可能构成了多态,又去掉子类的虚函数f(),但是子类已经被析构掉了!


原创粉丝点击