C++中的构造析构函数—2—虚析构函数

1. 构造函数不能定义为虚函数,每个对象的虚函数表指针是在构造函数中初始化的,因为构造函数没执行完,所以虚函数表指针还没初始化好。而析构函数可以定义为虚函数,也必须要定义为虚函数,否则在析构上无法体现出多态,导致子类的析构函数不会被调用,可能导致内存泄漏等风险。


2. 实验:

#include <iostream>

#define USE_VIRTUAL
#define OBJECT_DOG

class Animal {
public:
    Animal() {
        std::cout << "Animal object constructed !" << std::endl;
    };
    void Kill () {
        std::cout << "Kill Animal !" << std::endl;
    }
#ifdef USE_VIRTUAL
    virtual ~Animal() { //父类有 virtual 关键字修饰
        std::cout << "Animal object deconstructed !" << std::endl;
    }
#else
    ~Animal() { //父类无 virtual 关键字修饰
        std::cout << "Animal object deconstructed !" << std::endl;
    }
#endif
};

class Dog : public Animal {
public:
    Dog() {
        std::cout << "Dog object constructed !" << std::endl;
    }
    void Kill () {
        std::cout << "Kill Dog !" << std::endl;
    }
    ~Dog() { //子类有无 virtual 关键字修饰都行
        std::cout << "Dog object deconstructed !" << std::endl;
    }
};

#ifdef OBJECT_DOG
int main()
{
    Animal *p = new Dog();
    p->Kill();
    delete p;
}
#else
int main()
{
    Animal *p = new Animal();
    p->Kill();
    delete p;
}
#endif

实验结果:

//同时定义了 USE_VIRTUAL 和 OBJECT_DOG,可以看到构造和析构都正常:
# ./pp
Animal object constructed !
Dog object constructed !
Kill Animal !
Dog object deconstructed !
Animal object deconstructed !

//不定义 USE_VIRTUAL 只定义 OBJECT_DOG,可以看到Dog对象的析构函数没有被调用:
# ./pp
Animal object constructed !
Dog object constructed !
Kill Animal !
Animal object deconstructed ! //可以看到Dog对象的析构函数没有被调用!

 

posted on 2023-05-03 22:43  Hello-World3  阅读(44)  评论(0编辑  收藏  举报

导航