虚函数到底是什么?它与多态又是什么关系呢?

虚函数到底是什么?

虚函数的实际意义就是子类的成员函数把父类成员函数改写了一下,当子类成员的地址赋给父类指针变量时,子类的成员函数也随之覆盖了父类同名的成员函数。虚函数只限于有继承关系的类之间。

与虚函数相对应的多态又是什么?

多态通俗一点来讲就是有一个函数根据不同操作对象发挥不同的功能,即见人说人话,见鬼说鬼话。那多态的重要实现工具—虚函数所实现的多态通俗来讲就是一个函数它针对于有继承关系的不同类对象发挥不同功能。

多态性介绍:
关于C++中面向对象的多态特性,这里面先给大家介绍一下。什么是多态性?多态,即多种形态。在C++中一般是这么解释的:向不同的对象发送同一个消息,不同的对象在接收时会产生不同的行为。
之前其实已经给大家有使用过了,就是成员函数的重载,或者运算符的重载等等,都算是多态性的一种体现。
举个现实中的例子,我们还拿学生来做举例:说上课了,那么不同的学生可能会走进不同的教室,上课了,有的学生上语文课,有的学生上数学课,等等。所以针对同一个上课的消息,不同的学生产生的行为是不一样的。我相信大家一定会很容易明白吧。

下面我们用一个例子来说明:

// 多态与虚函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。  
//  
  
#include <iostream>  
using namespace std;  
  
class Cdog  
{  
protected:  
    float voice;  
    char *name;  
public:  
    Cdog(float voice, char *name);  
    ~Cdog();  
    virtual void Shvoice()  
    {  
        cout << "父类:" << this->name << "的音量为" << voice << endl;  
    }  
};  
Cdog::Cdog(float voice, char *name)  
{  
    this->voice = voice;  
    this->name = new char[strlen(name) + 1];  
    memset(this->name, 0, strlen(name) + 1);  
    strcpy(this->name, name);  
}  
Cdog::~Cdog()  
{  
    if (this->name)  
    {  
        delete[] this->name;  
        this->name = NULL;  
        cout << "调用Cdog类的析构函数释放内存" << endl;  
    }  
}  
class Cdog_golden:public Cdog  
{  
public:  
    Cdog_golden(float voice, char *name) :Cdog(voice, name) {};  
    ~Cdog_golden()   
    {  
        cout << "调用子类的析构函数" << endl;  
    };  
    void Shvoice()  
    {  
        cout << "子类:" << name << "的音量为" << voice << endl;  
    }  
};  
  
int main()  
{  
    char str[] = "金毛";  
    Cdog_golden Gdog(67, str);  
    Cdog *Dog = &Gdog;  
    Dog->Shvoice();  
} 

 

在这里我们父类的成员函数Shvoice()声明为virtual类型,这里的含义是当我们用父类指针指向子类成员对象时,指针指向的Shvoice()其实是子类的,而非父类。

结果是:

 

有些同学就会疑问:

因为在父类中父类Shvoice()的优先级高于子类的Shvoice()的优先级,因此父类的指针指向的Shvoice()函数不应该时父类的吗?这就体现了virtual虚函数声明标志的作用——屏蔽功能。

Virtual的意义是当父类指针访问子类对象时,自动将父类中的同名成员函数屏蔽掉,因为继承的作用是在原始类的基础上发展更新,屏蔽掉父类的低级功能使用子类中所声明的更高级的成员函数是我们都想要的,想使用的,因此只要将父类的成员函数声明为virtual之后,用指向子类对象的指针指向该成员函数时,都会采用子类同名成员函数中更高级的处理方式。

我们再试试下面不加virtual的情况:

// 多态与虚函数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。  
//  
  
#include <iostream>  
using namespace std;  
  
class Cdog  
{  
protected:  
    float voice;  
    char *name;  
public:  
    Cdog(float voice, char *name);  
    ~Cdog();  
    void Shvoice()  
    {  
        cout << "父类:" << this->name << "的音量为" << voice << endl;  
    }  
};  
Cdog::Cdog(float voice, char *name)  
{  
    this->voice = voice;  
    this->name = new char[strlen(name) + 1];  
    memset(this->name, 0, strlen(name) + 1);  
    strcpy(this->name, name);  
}  
Cdog::~Cdog()  
{  
    if (this->name)  
    {  
        delete[] this->name;  
        this->name = NULL;  
        cout << "调用Cdog类的析构函数释放内存" << endl;  
    }  
}  
class Cdog_golden:public Cdog  
{  
public:  
    Cdog_golden(float voice, char *name) :Cdog(voice, name) {};  
    ~Cdog_golden()   
    {  
        cout << "调用子类的析构函数" << endl;  
    };  
    void Shvoice()  
    {  
        cout << "子类:" << name << "的音量为" << voice << endl;  
    }  
};  
  
int main()  
{  
    char str[] = "金毛";  
    Cdog_golden Gdog(67, str);  
    Cdog *Dog = &Gdog;  
    Dog->Shvoice();  
} 

 

结果是:

我们看到如果不对父类中的同名函数声明为virtual类型,那就会默认访问父类的成员函数。因为在父类中父类成员函数的地位高于其他类的成员函数,那么父类指针就理所当然地访问在父类内优先级最高的成员函数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥肥胖胖是太阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值