C++中对C的扩展学习新增内容———面向对象(继承)纯虚函数和虚析构函数以及纯虚析构函数

纯虚函数和虚析构函数以及纯虚析构函数

纯虚函数(抽象类):

1、当一个类包含了纯虚函数,这个类就不能用来创建对象了。这个类叫做抽象类。

2、当一个类继承了父类的话,必须去重写父类的纯虚函数。如果子类不重写父类的纯虚函数,子类仍然是抽象类。

3、纯虚函数的实现:

class Animal
{
public:
    virtual void speak() = 0;  // 纯虚函数
};

虚析构函数以及纯虚析构函数:

1、通过父类指针释放子类对象问题

class Animal
{
public:

    Animal()
    {
        cout << "Animal 构造函数" << endl;
        p_name = new char[100];
    }

    virtual void speak()
    {
        cout << "Animal 说话..." << endl;
    }

    // virtual ~Animal() {}
    // virtual ~Animal() = default;  //C++11

    virtual ~Animal()
    {
        cout << "Animal 析构函数" << endl;
        if (p_name != nullptr)
        {
            delete[] p_name;
            p_name = nullptr;
        }
    }
public:
    char *p_name;
};


class Dog : public Animal
{
public:
    Dog()
    {
        cout << "Dog 构造函数" << endl;
        p_name2 = new char[100];
    }

    virtual void speak()
    {
        cout << "Dog 说话..." << endl;
    }

    ~Dog()
    {
        cout << "Dog 析构函数" << endl;
        if (p_name2 != nullptr)
        {
            delete[] p_name2;
            p_name2 = nullptr;
        }
    }
public:
    char *p_name2;
};


void test01()
{
    // 父类构造 子类构造
    Animal *animal = new Dog;
    animal->speak();

    // 
    delete animal;

    // 当多态发生时,如果通过父类指针去释放子类对象,默认情况只会调用父类的析构函数。可能会导致内存泄漏。
}

当多态发生时如果通过父类指针去释放子类对象,默认情况只会调用父类的析构函数。可能会导致内存泄漏。

2、虚析构函数的作用(通过父类指针去释放子类对象)没如果要实现多态,最好父类中增加一个虚析构函数。

3、虚析构函数和纯虚析构函数

(1) 纯虚析构函数要在类外增加函数体。

(2) 如果类的内部写了纯虚析构函数,该类就是抽象类(不能被实例化)。

(3) 一般情况下,写虚析构函数即可,类的内部有很多带有实现的虚函数,此时又希望该类为抽象类,此时我们可以将析构函数设置为纯虚析构函数,使得该类变成抽象类。

class Animal
{
public:

    Animal()
    {
        cout << "Animal 构造函数" << endl;
        p_name = new char[100];
    }

    virtual void speak()
    {
        cout << "Animal 说话..." << endl;
    }

    virtual ~Animal() = 0;  // 纯虚析构函数
public:
    char *p_name;
};

Animal::~Animal()
{

}


class Dog : public Animal
{
public:
    Dog()
    {
        cout << "Dog 构造函数" << endl;
        p_name2 = new char[100];
    }

    virtual void speak()
    {
        cout << "Dog 说话..." << endl;
    }

    ~Dog()
    {
        cout << "Dog 析构函数" << endl;
        if (p_name2 != nullptr)
        {
            delete[] p_name2;
            p_name2 = nullptr;
        }
    }
public:
    char *p_name2;
};

void test02()
{
    Animal *animal = new Dog;
    animal->speak();

    delete animal;
}

 

posted on 2019-11-19 21:24  YanShnY  阅读(337)  评论(0编辑  收藏  举报

导航