其他分享
首页 > 其他分享> > 多态、纯虚函数(抽象类)和虚析构

多态、纯虚函数(抽象类)和虚析构

作者:互联网

一.多态

多态:

1.静态多态:函数重载和运算符重载   //编译阶段确定函数地址

2.动态多态:派生类的虚函数实现运行时多态   //运行阶段确定函数地址

 

动态多态满足条件1.继承关系 2.子类重写父类虚函数

重新 :函数返回值类型 函数名 参数列表完全相同

动态多态的使用:父类的指针或引用指向子类对象

//多态
//动态多态满足条件1.继承关系 2.子类重写父类虚函数
//重新 :函数返回值类型 函数名 参数列表完全相同
class Animal
{
public:
    void speak() //添加virtual 虚函数  子类重写
    {
        cout << "说话" << endl;
    }
};
class Cat :public Animal
{
public:
    void speak()
    {
        cout << "猫说话" << endl;
    }
};
//执行说话
//地址早绑定,在编译阶段确定了函数地址 所有执行动物说话
void Aspeak(Animal& animal)  // Animal &animal=cat; 父类引用指向子类对象
{
    animal.speak();
}
int main()
{
    Cat cat;
    Aspeak(cat);
    return 0;
}

二.纯虚函数

在多态中,父类的虚函数实现是无意义的(通常调用子类重写内容),因此可以使用纯虚函数。

纯虚函数:virtual 返回值类型 函数名(参数列表)= 0

当类中有纯虚函数称为抽象类。

抽象类特点:

1.无法实例化对象(在class base中无法使用base b; / new base;创建对象)

// new返回的是该类型的指针 Base * p=new Son;

2.抽象类的子类 必须要重写父类中的纯虚函数,否则无法创建

class Base//类中有纯虚函数则称为抽象类
    {
    public:
        virtual void func() = 0;//纯虚函数
    };
class Son :public Base
{
    //2.抽象类的子类 必须要重写父类中的纯虚函数,否则无法创建
    //Son s;//无法创建
    virtual void func()
    {
        cout << "你好" << endl;
    }
};
int main()
{
    //1.抽象类无法实例化对象
    //Base b;
    //new Base;
    Base* base = new Son;
    base->func();

三.纯虚析构

 

在使用时若子类有属性开辟到堆区,父类指针无法释放子类对象则需要使用虚析构

 

虚析构和纯虚析构:

 

解决父类指针释放子类对象

 

都具有函数的实现

 

纯虚析构不能实例化对象

 

其中纯虚析构须要声明也需要实现(属于抽象类无法实例化对象)

class Animal
{
public:
    Animal()
    {
        cout << "A调用" << endl;
    }
    virtual void speak() = 0;
    //virtual ~Animal() //使用~Animal不会调用子类的虚析构,shiyongvirtual~aNIAML()可以解决该类问题
    //{
    //    cout << "删除" << endl;
    //}
    //纯虚析构
    virtual ~Animal()=0;
};
Animal::~Animal()
{
    cout << "纯虚删除" << endl;
}
class Cat:public Animal 
{
public:
    Cat(string name)//析构
    {m_name=new string(name);}
    virtual void speak()
    {cout <<*m_name<< "喵喵" << endl;}
    ~Cat()//虚析构
    {
        if (m_name != NULL) {
            delete m_name;
            m_name = NULL;}}
    string* m_name;};
int main()
{
    Animal* animal = new Cat("Tom");
    animal->speak();
    delete animal;//父类指针在析构时不会调用子类的析构,导致有数据泄露情况
    return 0;}

 

标签:函数,子类,多态,纯虚,抽象类,父类,虚析构
来源: https://www.cnblogs.com/lyj00/p/15826573.html