C++:多态公有继承中的虚方法
Posted 赵同学的代码时间
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++:多态公有继承中的虚方法相关的知识,希望对你有一定的参考价值。
派生类对象可以使用基类的方法,而未作任何修改,但是,某些情况下,我们会希望同一个方法在派生类中和基类中具有不同的功能,即,方法的行为应该取决于调用方法的对象,我们把这种较复杂的行为称为多态(顾名思义,具有多种形态)。
在C++中提供了两种机制可用于多态公有继承:
a. 在派生类中,重新定义基类方法
b. 使用虚方法
本文着重介绍方法b,使用虚方法实现多态公有继承。
虚 —— virtual
定义虚方法的关键字为virtual,在被定义成员函数的最前(返回类型前)加上该关键字,该方法则被定义为虚方法。请注意,虚方法与纯虚函数是不同的两个概念。
如果方法是通过引用或指针而不是对象进行调用,是否为虚方法将使得C++选择调用功能时发生差异。
如果没有使用虚函数标记virtual,程序将根据引用类型或指针的定义类型,选择调用方法,如果使用了虚函数标记virtual,程序将根据引用类型或指针指向的真实类型,选择调用方法。
Classname1 dom;
Classname2 dot;
//Classname2 由 Classname1 派生 且 存在虚方法show();
//由于存在虚方法,c1,c2按照指向类型去调用
Classname1 & c1 = dom;
Classname1 & c2 = dot;
c1.show();// 调用 dom 类型的show();
c2.show();// 调用 dot 类型的show();
//倘若不存在虚方法,将按照c1,c2的定义类型去调用
c1.show();// 调用 Classname1 类型的show();
c2.show();// 调用 Classname1 类型的show();
在基类中已经声明为虚方法,派生类中无论是否声明为虚方法,程序均会判定为虚方法,但为了便于阅读,建议都加上虚方法关键字virtual。
在基类中未定义为虚方法,在派生类中重新定义为虚方法,使用指向派生类的指针去调用该函数,程序并不会将其判定为虚成员函数。
总结 : 虚方法的声明是 向下兼容但向上不兼容的。
来自CSDN的测试实例:
以a指针类型指向派生类b时,调用M成员函数,由于A中M非虚方法,虽然B中声明M为虚方法,但程序还是调用了指针定义类型的成员函数,即基类中的方法M,说明,B中的声明对于该问题时是无效的。但如果以B作为基类,我们可以发现,无论M还是P成员函数,都被程序识别为虚方法,调用了指针指向的真实类型的成员函数。
虚析构函数
当理解了上述虚方法的实现特性后,我们便能更好的理解虚析构函数的必要性,倘若基类未定义一个虚析构函数,那么,我们使用指针或引用方法调用析构函数时,只会去调用指针定义类型的析构函数,倘如析构函数还需执行其他的功能,派生类中的析构函数就会被忽略,可能在实际调用中产生错误,因此,使用虚析构函数,是相当必要的,即使该虚构函数不需要执行任何操作。
有关虚函数的其他注意事项
关于虚函数的实现,静态动态联编,虚函数表等问题,将以后再谈,这里,再提示几个有关虚函数是其他注意事项。
要在派生类中重新定义基类的方法,则将它设置为虚方法,否则设置为非虚方法,这是由于静态联编和动态联编在效率上的考量;
在基类方法的声明中使用关键字virtual可以使该方法在基类及所有派生类(包括派生类派生类)都是虚方法;
如果使用指向对象的引用或指针来调用虚方法,程序将依照虚方法规则选择调用的方法,这称为动态联编,这使得基类指针或引用可以指向派生类对象;
如果定义的类将被用作基类,则应将那些要在派生类中重新定义的类方法声明为虚的。
以上是关于C++:多态公有继承中的虚方法的主要内容,如果未能解决你的问题,请参考以下文章