多态的定义 以及 虚函数重写(覆盖)

多态指的是 父类和子类在执行相同行为的时候,出现了不同的结果。而虚函数是实现多态的重要条件之一。下面以Person类和Student类来了解多态。

class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};

class Student : public Person {
public:
    // 子类的 virtual 可以不写,但是父类的必须写
	virtual void BuyTicket() { cout << "买票-半价" << endl; }    
};

目录

一、认识多态

1、多态的定义

2、多态的构成条件

二、虚函数的定义以及虚函数重写

1、什么是虚函数

2、虚函数重写的条件

3、虚函数重写示例

4、虚函数重写的两种特例情况

(1) 协变

(2) 析构函数的重写


一、认识多态

1、多态的定义

多态指的是 父类和子类在执行相同行为的时候,出现了不同的结果。成人和学生执行买票这种行为的时候,成人的结果是全票,学生的结果是半票。

实际上为了从语言的角度达到上述效果,其实就是父类Person 和子类Student 有着相同的成员函数 BuyTicket,父类去调用 BuyTicket 的结果是买全票,子类去调用 BuyTicket 的结果是买半票。我们的第一想法可能是这样

Person p;
p.BuyTicket();    // 成人买票

Student s;
s.BuyTicket();    // 儿童买票

但是这样的灵活性不强,于是引入了多态的概念,仅仅使用一个对象,就可以达到两种效果。

void Func(Person& p)
{ 
    p.BuyTicket(); 
}

int main(){
     Person ps;
     Student st;
 
     Func(ps);    // 传递Person对象买成人票
     Func(st);    // 传递Student对象买半票
}

2、多态的构成条件

在继承中要构成多态需要满足两个条件:

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

二、虚函数的定义以及虚函数重写

1、什么是虚函数

被 virtual 修饰的类成员函数称为 虚函数,这里的 virtual 跟之前虚继承里用到的 virtual 虽然是一个关键字,但是两者没有任何联系。

2、虚函数重写的条件

要重写虚函数需要满足一定的条件。既然是要让子类的某个函数来覆盖父类原本的函数,那就至少要求,子类的某个函数和父类的某个函数长得一模一样,这样才叫重写。

虚函数重写条件:派生类有一个函数跟基类完全相同虚函数。(函数名、形参、返回值相同)

3、虚函数重写示例

大前提是两者有继承关系,然后是两个类有完全相同的虚函数(其实子类不加virtual也可)

class Person {
public:
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};

class Student : public Person {
public:
    // 子类的 virtual 可以不写,但是父类的必须写
	virtual void BuyTicket() { cout << "买票-半价" << endl; }    
};

4、虚函数重写的两种特例情况

下面有两种特殊情况即便是不满足上述条件也构成虚函数重写

(1) 协变

协变指的是 基类和派生类的两个虚函数的返回值可以不同,但是返回值必须满足两个条件:

  • 返回值类型有继承关系
  • 返回值类型必须是指针 或者 引用
class Person {
public:
	virtual Person* BuyTicket() { cout << "买票-全价" << endl; }
};

class Student : public Person {
public:
	virtual Student* BuyTicket() { cout << "买票-半价" << endl; }
};

(2) 析构函数的重写

如果基类的析构函数为虚函数,无论是否加 virtual 关键字,都与基类的析构函数构成重写。

class Person {
public:
	virtual ~Person() { }
};

class Student : public Person {
public:
	virtual ~Student() { }    // 与派生类的析构函数构成重写(子类的 virtual 可以不写)
};

这是因为编译器对析构函数的名称进行了特殊处理,编译后析构函数的名称统一处理成 destructor

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值