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
再看结果,这样就解决了问题:
(后面少截了一段)