C++ 虚函数与多态

虚函数

虚函数是指在多态中,派生类和基类中存在返回类型、名字和参数形式都完全相同的函数,但是实现的函数体不同。

虚函数是多态的基础,没有虚函数就无法实现多态特性。在成员函数前加上一个virtual关键词就可以把函数设置为虚函数 ,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。

纯虚函数就是声明后面加上 =0 。

virtual void foo()=0;

纯虚函数在基类中只声明不定义,而在派生类中必须要定义。拥有纯虚函数的类成为抽象类,抽象类不能实例化。

虚函数的实现原理

当一个类带有虚函数时,编译系统会为该类构造一个虚函数表(指针数组),存放每个虚函数的入口地址。类创建的对象中,成员变量会占用内存空间,而成员函数是不占用内存空间的,但是如果类里有虚函数,这个对象就会有一个指针(指针大小取决于机器位数,32bit则是4B,64bit则是8B),指向虚函数表。这个指针存放在每个对象占用的内存空间的最前部,目的是可以快速地访问虚函数表。

虚函数表是数组而不是程序代码,因此存放在数据段而不是代码段。

派生类会复制基类的虚函数表。如果自己声明了新的虚函数的话,就会增加自己的虚函数入口地址。如果重写了基类的虚函数的话,那么就会覆盖同一个虚函数的入口地址。然后派生类的对象(无论是基类指针还是派生类指针指向这个对象)调用该虚函数的时候就是使用派生类写的函数内容,而不是基类的函数内容。

参考C++ 之虚函数的实现原理

img

多态

多态就是一个基类指针指向派生类对象时,他调用的虚函数是子类对象的虚函数。

比如说基类是Shape,派生类是Circle、Square,然后Shape中有一个虚函数area(),作用是求图形的面积,由于派生类Circle和Square求面积的方法不同,因此他们需要各自重写虚函数。如果有两个基类指针分别指向这两个派生类对象,则调用area函数时,返回的是他们各自的面积。

基类指针指向两个继承自同一基类的不同派生对象,调用同一个方法却执行了不同的动作,相当于让父类指针有多种形态,即多态。它是通过继承和虚函数实现的。

 
#include <iostream>
using namespace std;
class Shape {
public:
    virtual double area() const = 0; //纯虚函数
};
class Square : public Shape {
    double size;
public:
    Square(double s) {
        size = s;
    }
    virtual double area() const {
        return size * size;
    }
};
 
class Circle : public Shape {
    double radius;
public:
    Circle(double r) {
        radius = r;
    }
    virtual double area() const {
        return 3.14159 * radius * radius;
    }
};
int main()
{
    Shape* array[2]; //定义基类指针数组
    Square Sq(2.0);
    Circle Cir(1.0);
    array[0] = &Sq;
    array[1] =&Cir;
    for (int i = 0; i < 2; i++) /
    {
        cout << array[i]->area() << endl;
    }
    return 0;
}

关于基类和派生类的指针相互指向的问题有以下的情况。

  • 基类指针可以指向派生类对象,但只能直接引用基类的成员(要想操作派生类的数据成员,需要使用虚函数);
  • 派生类指针不可以指向基类对象,否则会引发语法错误。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值