C++多态

1.什么是多态

多态即不同的状态。在程序中体现为不同的对象去做同一行为的时候,状态、结果不同。在C++中通过基类的指针或引用调用虚函数时,不同的指针和引用会调用不同的函数。

2.多态的实现

2.1多态的条件

实现多态有两个条件:

1.虚函数重写

2.基类的指针或引用调用虚函数(指向谁调用谁的虚函数)

2.2虚函数

什么是虚函数呢,虚函数即为在类中被virtual修饰的类的非静态成员函数。如下例

class Base{
public:
    virtual void func()
    {
        cout<< "Base::func()" <<endl;
    }

};
class Derive : public Base{
public:
    //在多态里称为重写/覆盖
    virtual void func()
    {
        cout<< "Derive::func()" <<endl;
    }
};

 若上述Derive类中func()没有被virtual修饰与Base中的func()构成隐藏,但被修饰后再多态中被称为重写/覆盖。

实现了上示虚函数后,运行以下代码:

int main()
{
    Base b; Derive d;
    Base& b1 = b;
    Base& b2 = d;
    b1.func();
    b2.func();
    return 0;
}

结果如下,基类对基类对象和派生类的引用调用func()时分别调用了不同类的func()

2.3虚函数注意事项

1.虚函数需要满足三同(即函数名、参数、返回类型相同)

2.析构函数的多态,实际上编译后析构函数名字都处理为destructor(),析构函数建议设置为虚函数(涉及到资源释放等问题)

3.派生类的重写虚函数可以不加virtual,建议加上,使得层次跟清晰。

2.4C++11中的关键字

1.final 表示该函数不能被重写(放到基类中)

class Base{
public:
    virtual void func()
    {
        cout<< "Base::func()" <<endl;
    }

};
class Derive : public Base{
public:
    //在多态里称为重写/覆盖
    void func()final//此时再重写func()非法
    {
        cout<< "Derive::func()" <<endl;
    }
};

 2.final可修饰类(放在类名后),不可被继承,称为最终类

class Base{
public:
    virtual void func()
    {
        cout<< "Base::func()" <<endl;
    }

};
class Derive final : public Base{
public:
    //在多态里称为重写/覆盖
    virtual void func()
    {
        cout<< "Derive::func()" <<endl;
    }
};

此时Derive不可被继承

2.5重载、覆盖(重写)、隐藏(重定义)的对比

重载:

1.两个函数在同一作用域

2.函数名相同,参数不同

重写(覆盖):

1.两个函数分别在基类和派生类的类域

2.函数名、参数、返回类型相同

3.基类的指针或引用调用虚函数

重定义(隐藏)

1.两个函数分别在基类和派生类的类域

2.函数名相同

3.不构成重写

3.抽象类

3.1纯虚函数

纯虚函数没有函数体,在虚函数后面加上 = 0,如下func()即为纯虚函数

class Base {
public:
    virtual void func() = 0;
};

3.2抽象类概念

包含纯虚函数的类叫做抽象类(也叫接口 类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生 类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。

一般抽象类用于实现现实中抽象的事物,用于后续继承。

4.虚函数原理

实际上,当一个类中实现了虚函数,会在其对象中多存一个指针指向虚函数表,如下类

class Base {
    int a;
public:
    virtual void func()
    {

    }
};
class Derive : public Base {
public:
    virtual void func()
    {

    }
};

上示继承中Base::func()声明为虚函数,Base中存入一个虚函数表指针,虚函数表存放函数指针指向Base::func(),在Derive重写func()之后,虚函数表更新func()函数指针指向Derive::func(),如下图

总结:
1.多态原理:(虚函数)动态编译/动态调用/运行时绑定/动态绑定;(普通成员函数)编译时绑定/静态绑定。基类指针指向不同对象,调用其虚函数表指向的函数。

5虚函数注意事项

1.虚函数的重写也叫虚函数的覆盖

2.虚函数表的本质是函数指针数组,虚函数表存在常量区

3.虚函数的函数体存在代码段

4.虚函数表指针存在对象中

5.广义多态:

静态多态,函数重载,模版。

动态多态,虚函数。

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值