【C++】浅谈对多态的理解

多态

多态是C++中面向对象设计里一个重要的内容。所谓多态是指一个实体同时具有多种形式,通俗来讲就是同一个操作对于不同的对象,可以有不同的结果。
举个例子:

class Base
{
public:
    virtual void FunTest()
    {
        cout << "This is a Base class function" << endl;
    }
};
class Derived1: public Base
{
public:
    virtual void FunTest()
    {
        cout << "This is a Derived1 class function" << endl;
    }
};
class Derived2 : public Base
{
public:
    virtual void FunTest()
    {
        cout << "This is a Derived2 class function" << endl;
    }
};
int main()
{
    for (int i = 0; i < 10;i++)
    {
        Base* b;
        int a;
        cin >> a;
        if (a % 2 == 1)
            b = new Derived1;
        else
            b = new Derived2;
        b->FunTest();
    }
    return 0;
}

多态可以分为静态多态和动态多态:

  • 静态多态:发生在编译阶段,具体变现为函数重载,泛型编程。
  • 动态多态:发生在程序运行时,需要满足两个条件。
    -1.虚函数,在派生类中对基类虚函数重写;
    -2.在继承体系中,通过基类类型的指针或引用来调用虚函数。

虚函数:在基类,使用关键字virtual声明,并在派生类中进行重写,用于实现多态性,通过基类的指针或引用调用。
注:1.在派生类中可以不加virtual,但建议加上,代码可读性较强。
  2.如果在类外定义虚函数,只能在函数声明时加virtual关键字,在定义时不需要。
重写:在继承体系中,如果基类中有虚函数,在派生类中有和基类虚函数原型完全相同的函数。
注:两个例外
  1.协变:基类返回基类指针(或引用),派生类返回派生类的指针(或引用);
  2.析构函数:建议最好将析构函数声明为虚函数。
  
构造函数,友元函数,静态函数不能声明为虚函数,赋值运算符重载不建议声明为虚函数,为什么?
  对于构造函数,从内存的角度看,虚函数的调用需要虚表,虚表储存在对象的内存空间,如果构造函数声明为虚函数,那就需要虚表来调用,但是对象没有实例化,没有内存空间,更没有虚表来调用构造函数了;另外,构造函数的调用是创建对象时自动调用的,而虚函数的调用是通过基类的指针去调用,所以构造函数不能声明为虚函数;
  对于友元函数和static修饰的静态函数,友元函数不属于该类的成员函数,不能被继承,虚函数的调用需要对象,也不能声明为虚函数;静态函数可以被继承,但对于静态函数,每个类共享一份代码,它是属于类的,调用不需要对象,所以不能声明为虚函数;
  赋值运算符重载,将赋值运算符重载声明为虚函数,容易造成混淆,因为虚函数要求必须在基类和派生类中函数原型相同,参数也就需要相同,基类的形参是自身类型的引用,派生类的形参也为基类类型的引用,对派生类而言,这个操作符与复制操作并不相同,造成程序赋值运算混乱;
  析构函数,基类的指针指向派生类的对象,如果涉及到动态内存开辟,析构函数如果没有声明为虚函数,那么使用基类指针调用析构函数可能会造成内存泄漏,所以建议将析构函数声明为虚函数。

 函数的重载,继承体系中的同名隐藏,多态中的重写极其相似,但仍有所区别:
1 .函数的重载:在同一个作用域,函数名相同,参数列表不同,与返回值类型无关;
2 .同名隐藏:在继承体系中,如果基类和派生类有相同的名称的成员,如果使用派生类对象调用基类和派生类中的同名成员,优先调用派生类中的成员,同名成员仅名称相同,与函数原型无关,与类型无关;
3 .函数重写(覆盖):在继承体系中,如果基类中有虚函数,在派生类中有和基类虚函数原型完全相同的函数。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值