【问题标题】:Missing Derived class Destructor when object is created with the base class pointer使用基类指针创建对象时缺少派生类析构函数
【发布时间】:2020-07-12 15:19:49
【问题描述】:

在以下代码示例中,未调用派生类析构函数。知道为什么吗? 我有一个具有虚函数的基类。现在我使用基类指针来创建派生类的新对象。我的理解是当派生类对象被销毁时,派生类的析构函数首先被调用,然后是基类。但是我只看到基类的析构函数被调用。有谁知道我做错了什么或者我对 c++ 的理解不正确?

#include <iostream>
#include <bitset>
using namespace std; 

class DomesticAnimals 
{
    public:
        DomesticAnimals() {
            cout <<"Domestic Animal Base" <<endl;
        }; 
        ~DomesticAnimals() {
            cout <<"Domestic Animal kill " <<endl;
        }; 
        virtual void Speak() = 0;
        virtual void EatFood()= 0; 
        virtual int NoOfLegs() {
            return 4; 
        } ;
};


class Cat : public DomesticAnimals
{
    public:
        Cat(); 
        ~Cat(); 
        void Speak() override; 
        void EatFood() override; 
};

Cat::Cat()
{
    cout << "Kat was born" << endl;
}

Cat:: ~Cat()
{
    cout << "Kill de Cat" << endl; 
}
void Cat:: Speak()
{
    cout << "Meow Meow " << endl; 
}

void Cat::EatFood()
{
    cout <<"Kat eet de muis vandaag !! " <<endl; 
}


class Dog : public DomesticAnimals
{
    public:
        Dog();
        ~Dog();
        void Speak() override; 
        void EatFood() override; 
};

Dog::Dog()
{
    cout << "A puppy was born" << endl; 
}

Dog::~Dog()
{
    cout << "Kill de hond" << endl; 
}

void Dog :: Speak()
{
    cout <<"bow bow woof woof" <<endl;
}

void Dog :: EatFood()
{
    cout << "de hond eet een kip voor middageten" <<endl;
}

void DogActions()
{
    DomesticAnimals* dog = new Dog;
    cout<< endl;
    dog->Speak(); 
    dog->EatFood();
    cout<<"No of legs for dog = "<< dog->NoOfLegs() <<endl; 
    cout<<endl;
    delete dog; 
    dog = NULL;
}

void CatActions()
{
    DomesticAnimals* cat = new Cat; 
    cat->Speak(); 
    cat->EatFood(); 
    cout<<"No of legs for cat = "<< cat->NoOfLegs() << endl;
    delete cat; 
    cat = NULL; 
}

int main(void)
{
    DogActions();
    CatActions();
    return 0;
}

程序的输出如下

Domestic Animal Base
A puppy was born

bow bow woof woof
de hond eet een kip voor middageten
No of legs for dog = 4

Domestic Animal kill 
Domestic Animal Base
Kat was born
Meow Meow 
Kat eet de muis vandaag !! 
No of legs for cat = 4
Domestic Animal kill 

【问题讨论】:

  • 对于多态基类,析构函数必须virtual。如果您的教科书、教程或老师没有提及,请考虑更换书籍、教程或课程。
  • 这并没有解决问题,但是将NULL 分配给即将超出范围的指针并不能解决任何问题。指针不存在,因此它的值无关紧要。从DogActions 中删除dog = NULL; 和从CatActions 中删除cat = NULL;

标签: c++ gcc constructor destructor


【解决方案1】:

基类的析构函数需要是虚拟的:

virtual ~DomesticAnimals() {
    cout << "Domestic Animal kill" << endl;
};

为了避免任何混淆(参见 cmets):只有在通过指向其基类的指针删除对象的情况下才需要使析构函数为虚拟。这通常是需要多态性的情况。

【讨论】:

  • 基类的析构函数没有一般要求必须是虚拟的。析构函数必须是虚拟的 if 代码将通过指向基的指针删除派生类型的对象。这就是这段代码中的问题,将析构函数设为虚拟可以解决它。
  • 我正在回答他的问题:“我的理解是当派生类对象被销毁时,派生类的析构函数首先被调用,然后是基类。”为了实现这一点,基本析构函数需要是虚拟的。我并不是在声明一般要求。
  • 你的回答不是这样的。
猜你喜欢
  • 1970-01-01
  • 2013-08-30
  • 2020-08-12
  • 2020-08-06
  • 2014-06-16
  • 2021-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多