面向对象三大特性之一——多态详解

本文详细讲解了面向对象的多态特性,包括多态的概念、虚函数的定义与重写,以及c++11的`override`和`final`关键字。探讨了多态的构成条件,如必须通过基类指针或引用调用虚函数,以及多态的实现原理,如虚函数表和动态绑定。还介绍了抽象类的概念及其在多态中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

一、多态的概念

二、多态的定义及实现

 1、虚函数的概念

2、虚函数的重写

2.1概念

2.2虚函数重写的两个例外 

3、多态的构成条件

4、c++ 11 override和final

4.1 final

4.2 override

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

三、抽象类

1、概念

2、接口继承和实现继承 

四、多态的原理

1、虚函数表

2、多态的原理

3、动态绑定和静态绑定

 五、继承的虚函数表

1、单继承中的虚函数表

 2、多继承中的虚函数表

六、常见面试题

总结


前言

哈喽,小伙伴们大家好。上一章我们一起学习了继承,今天我们继续来学习面向对象三大特性中的最后一个特性——多态。事不宜迟,快拿起小本本,跟我一起开始吧。


一、多态的概念

概念:多态,顾名思义,也就是多种状态。通俗点说就是不同的对象去干同一件事情时会产生不同的状态。以买火车票为例,普通人买票就要付全款,学生买票就可以出半价,军人虽然不能优惠但是可以优先买票。

放到我们程序中就是不同继承关系的类对象去调用同一个函数,会产生不同的状态。

二、多态的定义及实现

 1、虚函数的概念

在了解多态的构成条件前,我们先来了解一个概念,虚函数。

虚函数:被virtual修饰的类成员函数称为虚函数。要注意,虽然虚函数的关键字和虚拟继承的关键字相同,但实际它们没有任何关系。

2、虚函数的重写

2.1概念

虚函数的重写(覆盖):派生类中有一个和基类中完全相同的虚函数(函数名,返回值,参数列表都相同),则成为子类对基类的虚函数进行了重写。

注意:如果基类的函数为虚函数,不管派生类的相同函数前加不加virtual,都默认是虚函数,进行了重写。

class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
	virtual void BuyTicket() { cout << "买票-半价" << endl; }
	/*注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因
	为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议
	这样使用*/
};

2.2虚函数重写的两个例外 

虚函数重写一般要严格遵守函数完全相同的条件,但是有两个例外情况下这个规则被打破。

(1)协变(返回值不同)

派生类重写基类的虚函数时,与基类虚函数返回值不同。如果派生类虚函数返回的是派生类对象的引用或指针,基类虚函数返回的是基类对象的引用或指针,则构成协变。这种情况下可以看作进行了虚函数重写。虚函数一般很少使用,了解即可。

class A {};
class B : public A {};
class Person {
public:
	virtual A* f() { return new A; }
};
class Student : public Person {
public:
	virtual B* f() { return new B; }
};

(2) 析构函数重写(名字不同)

如果基类的析构函数为虚函数,则与派生类的析构函数进行重写。虽然这两个函数看上去名字并不相同,但编译器进行了处理,编译后析构函数的名称统一编译成destructor。、

class Person {
public:
    virtual ~Person() {cout << "~Person()" << endl;}
};
class Student : public Person {
public:
    virtual ~Student() { cout << "~Student()" << endl; }
};

// 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函
//数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。
int main()
{
    Person* p1 = new Person;
    Person* p2 = new Student;
    delete p1;
    delete p2;
    return 0;
}

注意:我们在写多态时,尽量不要出现协变,并且基类和派生类的虚函数前面都加上virtual,使代码更规范。

3、多态的构成条件

多态的构成条件:

  • 被调用的必须是虚函数,且派生类必须对基类的虚函数进行了重写。
  • 必须通过基类的指针或引用调用虚函数。

我们以普通人和学生买票为例,代码如下:

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值