多态

多态在C++中是通过虚函数实现的,通过前面的模型【参见“有重写的单继承”】知道,如果类中有虚函数,编译器就会自动生成一个虚函数表,对象中包含一个指向虚函数表的指针,能够实现多态的关键在于:虚函数时允许被派生类重写的,在虚函数表中,派生类函数对覆盖基类函数。初次之外,还必须通过指针或引用调用方法才行,将派生类对象赋给基类对象。

wKioL1fIGVSiUANmAAAerJGMzkg291.png-wh_50

上面两个类,基类派生类中都包含两个方法

void print() const;
virtual void print_virtual() const;

这两个方法的区别就是一个是普通成员函数,一个是虚函数,编写代码如下

void test_polmorphisn()
{
Base b;
Derived d;

b = d;
b.print();
b.print_virtual();

Base *p;
p = &d;
p->print();
p->print_virtual();
}

根据模型推测,只有p->print_virtual()才实现了动态,其他3调用基类方法,原因如下:

1)b.print();b,print_virtual();不能实现多态是因为通过基类对象调用,而非指针或引用所以不能实现多态。

2)p->print();不能实现多态是因为,print函数没有生命为虚函数,派生类中也定义了print函数知识隐藏了基类的print函数。

为什么析构函数设为虚函数是不要的?

析构函数应当都是虚函数,除非明确该类不做基类(不被其他类继承),基类的析构函数声明为虚函数,这样做是为了确保释放派生类对象时,按照正确的顺序调用析构函数。

从C++对象模型可以知道,如果析构函数不定义为虚函数,那么派生类就不会重写基类的析构函数,在有多态行为的时候,派生类的析构函数不会被调用到。

例如,通过new一个派生类对象,赋给基类指针,然后delete基类指针

void test_vitual_destructor()
{
Base *p = new Derived();
delete p;
}

如果基类函数不是析构函数

wKioL1fIHaexEGrzAAAD06ojXos045.png

注意,缺少派生类的析构函数调用,把析构函数声明为虚函数,调用就正常了

wKioL1fIHePxet6sAAADmUkNJzs794.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章