虚函数

第15章的主题是面向对象编程(Object-Oriented),其中3个关键概念为数据抽象、继承和动态绑定。用类进行数据抽象,用类派生从一个类继承另一个类,动态绑定使编译器在运行时决定使用基类或派生类中的函数。多态性(polymorphism)和虚函数(virtual function)是C++中的重要概念,我将这些东西记录下来,希望能更彻底地搞懂虚函数。

 

一、什么是虚函数?

C++中通过设定虚函数指出希望派生类来重定义那些函数。除构造函数为,任何非static成员函数都可以为虚成员。
因为基类类型的指针也可以指向派生类对象,当通过基类类型的指针或引用调用虚函数时,会发生动态绑定,具体运行哪个虚函数将在运行时确定,根据该指针所实际指向的对象类型类确定。

记住:C++中的动态绑定有两个条件

(1)、成员函数为虚函数;

(2)、必须通过基类类型的引用或指针进行函数调用。
考虑如下代码:

class Base{
public:
virtual void print(){
cout << "Base print()" << endl;
}
};
class Derived : public Base{
public:
virtual void print(){
cout << "Derived print()" << endl;
}
};
int main{
Derived dObj;
Base item(dObj);
Base *p = &dObj;
item.print(); //输出结果为 Base print()
p->print(); //输出结果为 Derived print()
}

p为Base类型的指针,当通过p调用虚函数print()时,编译器将生成代码,在运行时确定调用哪个函数。由于p实际指向的是Derived对象,所以将调用Derived版本的print()。
你也可以使用域操作符强制调用某个虚函数版本:

p->Base::print(); //输出结果为Base print()

一旦函数在基类中声明为虚函数,她就一直为虚函数,派生类可以使用或不使用virtual保留字。
派生类中的虚函数的声明必须与基类中的定义方式完全匹配,但是呢,有一个例外:返回类型为对基类型的引用或指针。

In Base:
virtual Base& func();//返回类型为Base&,所以它的派生类中的声明可以与此不同,如下。
In Derived:
Derived& func();//可以不使用virutal保留字,func仍为虚函数。

二、纯虚函数

class Derived2 : public Base{
public:
void func() const=0; //声明为虚函数
};

将函数定义为纯虚函数,则为其后代类型提供了覆盖接口,但这个类中的版本决不会调用。而且,用户将不能创建该类的对象,这种类称为抽象基类。
就是说,你不会去创建一个抽象基类的对象,它只起到一个过渡的作用。
三、虚析构函数
一般继承层次的基类都应该定义一个虚析构函数。但是,为虾米呢?
当删除指向动态分配对象的指针时,需要运行析构函数在释放对象的内存之前清除对象。
如果我们删除一个基类指针时,则需要运行基类析构函数并清除基类的成员,若该指针实际是指向的是派生类对象,这种行为是没有定义的。将基类的析构函数设为虚函数,具体运行哪个析构函数则将因指针所指对象的类型不同而不同。

class Base:{
public:
virtual ~Base() {} //没干啥事,但却是是需要的,当你删除一个指向派生类对象的基类指针时就知道了。
};
class Derived : public Base{
public:
virtual ~Derived() {}
};
Base *itemP = new Base;
delete itemp;//OK,将调用~Base()
itemP = new Derived();
delete itemP;//此时将会先调用~Derived()

如果~Base()不是虚函数,在delte itemP时,将只会调用~Base(),而itemP指向的是派生类对象,这显然是不合理的。
所以,以保证在删除(指向动态分配对象)基类指针时,根据指针实际指向的对象所属的类型运行适当的析构函数。

原文链接: https://www.cnblogs.com/adriano/archive/2010/09/12/1824291.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    虚函数

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/14916

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午2:45
下一篇 2023年2月7日 下午2:47

相关推荐