skip to Main Content
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;
}

The delete is causing an error. Why is that?
Attempt to release memory via delete without using destructors, but an error occurs
"Delete called on’animal’ that is abstract but has non-virtual destruct
Thread 1: signal SIGABRT"

2

Answers


  1. The error is telling you what the issue is. You are destroying your virtual objects with a non-virtual destructor.

    You have virtual void cry why? Its so that when you call animal->cry, it calls the Cat cry, not the default Animal cry. The same is true of the virtual destructor. When you call delete animal you need it to call the destructor of the actual object, not just the base class. You need to add:

    virtual ~Animal() = default;
    

    to your animal class.

    A base class destructor should be either public and virtual, or protected and non-virtual

    Cpp Core Guidelines

    As for the second issue, the double delete:

    delete animal; // deletes the object
    delete cat; // deletes the same object again, because cat and animal point to 
                // the same place.
    

    Some suggest to not delete twice, i would suggest to not call delete explicitly at all. Use a smart pointer:

    auto animal = std::make_unique<Cat>();
    Cat &cat = *animal;
    
    animal->cry();
    cat.cry(); // Calls the same function as above.
    

    Unique pointer will handle the deletion of the object for you.

    Login or Signup to reply.
  2. You are trying to delete the same object twice:

    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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search