C++——多态

一.定义

1.1

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

1.2

多态分为静态多态与动态多态。

静态多态:函数重载,运算符重载。

动态多态:派生类与虚函数实现实现运行时多态。

条件:

1.有继承关系

2.子类重写父类的虚函数

1.3

在继承中要构成多态还有两个条件:

1. 必须通过基类的指针或者引用调用虚函数

2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

1.4

虚函数(Virtual Functions)

  • 在基类中声明一个函数为虚函数,使用关键字virtual
  • 派生类可以重写(override)这个虚函数。
  • 调用虚函数时,会根据对象的实际类型来决定调用哪个版本的函数。

二.实例

2.1基本应用

#include <iostream>
#include<cstring>
using namespace std;

class Person {
public:
	virtual void BuyTicket() { cout << "我是父类" << endl; }   //父类中virtual一定要写
};

class man:public Person{
    virtual void BuyTicket() { cout << "我是子类1" << endl; }
};

class woman:public Person{
    virtual void BuyTicket() { cout << "我是子类2" << endl; }
};

void use(Person &p1){         //使用指针或引用
    p1.BuyTicket();
}

int main()
{
    Person x0;
    man x1;
    woman x2;
    use(x0);
    use(x1);
    use(x2);        //根据传入的对象不同,执行不同的部分(类似函数重载)
	return 0;
}

注意:接受对象为父类的指针或者引用,你传递的是父类就调用父类的函数,传递的是子类就调用子类的函数,

在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用。

2.2纯虚函数与抽象类

在虚函数的后面写上 =0 ,则这个函数为纯虚函数包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。另外,抽象类的子类也必须重新纯虚函数,否则也属于抽象类。

#include <iostream>
#include<cstring>

using namespace std;

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

class man:public Person{
    public:
    virtual void func(){             //只有重写了纯虚函数,子类才不会变成抽象类
        cout << "抽象类的子类" << endl;
    }
};

int main()
{
    //Person p;  抽象类无法实例化对象
    //new Person;抽象类无法实例化对象
    man a;
    a.func();
	return 0;
}

2.3析构函数的重写

#include <iostream>
#include<cstring>

using namespace std;

class Person {
public:
	virtual ~Person(){
        cout << "父类的析构" << endl;
    }
};

class man:public Person{
    public:
    virtual ~man(){
        cout << "子类的析构" << endl;
    }
   
};

int main()
{
    Person *p1 = new Person;
    man *p2 = new man; 
    delete p1;
    delete p2; 
	return 0;
}

如果以上代码中的析构函数前没有加virtual的话,p2(子类对象)只会析构父类,可能发生内存泄漏,因为子类应该调用子类的析构再调用父类的析构。

为什么:

因为这里发生了隐藏,~Person()变为 this->destructor()  ~Student()为this->destructor() 

编译器将他们两个的函数名都统一处理成了destructor,因此调用的时候只看自身的类型,是Person就调用Person的函数,是Student就调用Student的函数,根本不构成多态,这并不是我们期望的那样

注意:析构函数加virtual是在new场景下才需要, 其他环境下可以不用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值