#include <iostream>
using namespace std;
class Animal{
public:
virtual void cry() = 0;
void eat();
};
class Cat:public Animal
{
public:
virtual void cry();
void grooming();
};
class Dog:public Animal
{
public:
virtual void cry();
void lash();
};
main()
{
Animal* animal = new Cat();
animal->eat();
animal->cry();
Cat* cat = (Cat*)animal;
cat->grooming();
Dog* dog = new Dog();
dog->cry();
dog->eat();
dog->lash();
delete animal; //Delete called on'animal' that is abstract but has non-virtual destruct
delete cat; //Thread 1: signal SIGABRT
delete dog;
}
删除导致错误。这是为什么? 尝试在不使用析构函数的情况下通过delete释放内存,但出现错误 "删除名为'animal'的抽象但具有非虚拟析构的对象 线程 1:信号 SIGABRT"
该错误告诉您问题是什么。您正在使用非虚拟析构函数销毁虚拟对象。
你有
virtual void cry
为什么?这样,当您调用 animal->cry
时,它会调用 Cat
哭声,而不是默认的 Animal
哭声。虚拟析构函数也是如此。当您调用 delete animal
时,您需要它来调用实际对象的析构函数,而不仅仅是基类。您需要添加:
virtual ~Animal() = default;
到你的动物课。
base类析构函数应该是公共和虚拟的,或者是受保护的和非虚拟的
至于第二期,双重删除:
delete animal; // deletes the object
delete cat; // deletes the same object again, because cat and animal point to
// the same place.
有些人建议不要删除两次,我建议根本不要显式调用删除。使用智能指针:
auto cat = std::make_unique<Cat>();
Animal &animal = *cat;
animal.cry();
cat->cry(); // Calls the same function as above.
唯一的指针将为您处理对象的删除。
您尝试两次删除同一个对象:
Animal* animal = new Cat();
Cat* cat = (Cat*)animal; // cat points to the same object as animal
...
delete animal; // first delete
delete cat; // second attemp fails