关于c++多态以及虚函数的些许疑惑及解释

本文通过实例讲解了C++中多态的概念及其实现方式,解释了虚函数的作用,并介绍了虚函数表的工作原理。

在学习c++多态时,心里总是有些疑惑:什么是多态?什么是虚函数?

开始并不在意,但是在学习抽象类时问题出现了。所以现在又翻回头来重新咀嚼一下多态以及虚函数。

参考文章:C++ 虚函数经典深入解析    c++虚函数详解

何为多态?

简而言之,就是让父类拥有多种形态,通过父类来实例化子类对象,然后用父类对象调用子类成员函数。

而要实现这些,一个很重要的工具就是虚函数(函数的隐藏与覆盖)。

下面看个例子来理解一下虚函数:

#include <iostream>  
#include <list>  
#include <string>  
using namespace std;  
class Employee  
{  
public:  
    string strName;  
    Employee()  
    {  
    }  
    Employee(string strName)  
    {  
        name = strName;  
    }  
    virtual void PrintE()  
    {  
        cout<<name<<" is a employee"<<endl;  
    }  
private:  
    string name;  
};  
class Manger : public Employee  
{  
public:  
    Manger(string strname)   
    {  
        name = strname;  
    }  
    void PrintE()  
    {  
        cout<<name<<" is a manger"<<endl;  
    }  
private:  
    string name;  
};  
int main()  
{  
    Employee *ep = new Employee("Bill");  
    Employee *mg = new Manger("john");  
    list<Employee*> lstEp;  
    lstEp.push_back(ep);  
    lstEp.push_back(mg);  
    for (list<Employee*>::iterator iter = lstEp.begin(); iter != lstEp.end(); iter++)  
    {  
        (*iter)->PrintE();  
    }  
    delete ep;  
    delete mg;  
    getchar();  
}

父类employee下有子类manger,如果对于manger函数来说,通过父类实例化的子类对象调用不加virtual的函数printE时,实际上调用的父类的printE函数,如果想要调用子类的函数,则需要给父类的函数加上关键字virtual。

我们在从原理上理解一下:

了解c++的人应该明白:虚函数的实现依赖于虚函数表,对于c++来说,虚函数表就是一个类中虚函数的地址表,学习过c语言的应该知道函数指针,函数在内存中实际上是一段二进制代码,函数指针则是二进制代码在内存中的起始地址。而虚函数表中存放的是所有虚函数的函数指针。

可以这样理解:

通过父类实例化子类对象后得到一个子类对象,而子类对象的首地址则是虚函数表的地址(指针4个字节)。


circle是子类,shape是父类。

大家可以想一下,如果在父类中不将calcArea计算面积函数定义为虚函数,在子类中,该函数将被继承下来,而在通过对象调用时当然调用的是父类的calcArea函数





我们可以看到最后的结果是:shape

而如果将父类的calcArea函数定义为virtual,而子类中对calcArea函数进行了不同的实现,所以子类中虚函数表的虚函数指针所指向的函数不一样。

所以当我们用父类的指针指向子类的对象时,他就会通过子类的虚函数表找到子类中的虚函数,从而实现多态。

而为什么子类的函数不加virtual也会默认是虚函数呢?

因为它继承了父类。



这就是本篇文章的全部内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值