c++中的多态

  • 多态的定义及实现
  • 抽象类
  • c++11中的override和final
  • 多态的原理
  • 单继承和多继承关系中的虚函数表

1. 多态的定义及实现

1.1 多态的概念

通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生不同的状态

1.2 多态定义的构成条件

0.前提是继承

  1. 调用函数的对象必须是指针或者引用。
  2. 被调用的函数必须是虚函数,且完成了虚函数的重写。

1.3 虚函数的概念及虚函数的重写

虚函数的概念:就是在类的成员函数的前面加virtual关键字

虚函数的重写:

虚函数的重写:派生类中有一个跟基类的完全相同虚函数,我们就称子类的虚函数重写了基类的虚函数,完全相同是指:函数名、参数、返回值都相同。另外虚函数的重写也叫作虚函数的覆盖。

//多态前提:继承
class Person {
public:
    virtual void BuyTicket() { cout << "买票-全价"  << endl; }
};
class Student : public Person {
public:
    virtual void BuyTicket() { cout << "买票-半价"  << endl; }
};
void Func(Person& p)
{
    p.BuyTicket();   
}
int main()
{
    Person ps;
    Student st;
    //多态看实际指向的对象,调用对象对应类型的代码
    //非多态看类型
    Func(ps);
    Func(st);
    return 0;
}

1.4 虚函数重写的例外:协变

虚函数重写有一个例外:重写的虚函数的返回值可以不同,但是必须分别是基类指针和派生类指针或者基类引用和派生类引用。

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; }
};

1.5 析构函数的重写问题

基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。这里他们的函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor,这也说明的基类的析构函数最好写成虚函数。

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;
}

1.6 接口继承和实现继承

普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口。所以如果不实现多态,不要把函数定义成虚函数。

1.7 重载、覆盖(重写)、隐藏(重定义)的对比
在这里插入图片描述
2. 抽象类

在虚函数的后面写上 &

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值