继承多态

1.继承的构造和析构的顺序

子类继承父类:
(1)父类构造函数
(2)子类构造函数
(3)子类析构函数
(4)父类析构函数

不管怎么调用子类结果都是一样的:

//通过父类创建子类
Animal *cat = new Cat();
delete cat;
cat = NULL;
cout<<endl;
//子类自己创建自己
Cat *c = new Cat();
delete c;
c = NULL;
cout<<endl;
//或者非指针的方式
Cat cat1;

继承多态
(后面少截了一段)

2. 父类释放子类指针问题

现在子类存在带有指针的类:
父类Animal.hpp:

//
// Created by Administrator on 2021/7/16.
//

#ifndef C__TEST01_ANIMAL_HPP
#define C__TEST01_ANIMAL_HPP
#include "iostream"

class Animal {
public:
    string *name;
public:
    Animal();
    //virtual ~Animal() = 0; //纯虚析构,纯虚析构必须在类外实现
    ~Animal();//没用虚析构的情况
    virtual void doSpeak() = 0;//纯虚函数,相当于java的接口,子类必须重写父类方法
};

Animal::Animal() {
    name = new string("animal");
    cout<<"Animal abstract class construction"<<endl;
}

//为了帮助解决父类释放子类指针的问题
Animal::~Animal() {
    if(name !=NULL)
    {
        delete name;
        name = NULL;
    }
    cout<<"Animal Destructor"<<endl;
}

#endif //C__TEST01_ANIMAL_HPP

子类Cat.hpp:

//
// Created by Administrator on 2021/7/16.
//

#ifndef C__TEST01_CAT_HPP
#define C__TEST01_CAT_HPP

#include "iostream"
#include "Animal.hpp"

class Cat :public Animal{
private:
    string *name;
public:
    Cat();
    ~Cat();
    virtual void doSpeak();
};

Cat::Cat() {
    name = new string("tom");
    cout<<"Cat class construction"<<endl;
}
Cat::~Cat() {
    if(name !=NULL)
    {
        delete name;
        name = NULL;
    }
    cout<<"Cat Destructor"<<endl;
}

void Cat::doSpeak() {
    cout<<name<<"在说话函数"<<endl;
}
#endif //C__TEST01_CAT_HPP

我们再在main中调用:

#include <iostream>
using namespace std;

//类的继承多态
#include "Cat.hpp"
int main() {
    //通过父类创建子类
    Animal *cat = new Cat();
    delete cat;
    cat = NULL;
    cout<<endl;
    //子类自己创建自己
    Cat *c = new Cat();
    delete c;
    c = NULL;
    cout<<endl;

    Cat cat1;
    return 0;
}

结果:
继承多态
从结果可知:第一个用父类指针new子类, 父类并不能释放子类指针!
但是直接子类new子类就不会出现问题,我们在实际应用中肯定会用父类new子类,所以解决办法就是将父类的析构函数换成纯虚析构或者虚析构函数:
代码只需加个virtual:

//
// Created by Administrator on 2021/7/16.
//

#ifndef C__TEST01_ANIMAL_HPP
#define C__TEST01_ANIMAL_HPP
#include "iostream"

class Animal {
public:
    string *name;
public:
    Animal();
    virtual ~Animal() = 0; //纯虚析构,纯虚析构必须在类外实现
    //~Animal();//没用虚析构的情况
    virtual void doSpeak() = 0;//纯虚函数,相当于java的接口,子类必须重写父类方法
};

Animal::Animal() {
    name = new string("animal");
    cout<<"Animal abstract class construction"<<endl;
}

//为了帮助解决父类释放子类指针的问题
Animal::~Animal() {
    if(name !=NULL)
    {
        delete name;
        name = NULL;
    }
    cout<<"Animal Destructor"<<endl;
}

#endif //C__TEST01_ANIMAL_HPP

再看结果,这样就解决了问题:
继承多态
(后面少截了一段)

上一篇:Java基础知识


下一篇:ts类型保护