Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Pure virtual destructor in abstract class with members

I've just started learning C++ and stumbled across this problem.. I've written this abstract class with pure virtual destructor:

#ifndef ANIMAL
#define ANIMAL
#include <string>
using namespace std;

class Animal {
public:
    Animal();
    virtual ~Animal() = 0;
    Animal(string name, int age);
    virtual string says() = 0;
    void setName(string name);
    void setAge(int age);
    string getName() const;
    int getAge() const;

private:
    int _age;
    string _name;
};
inline Animal::~Animal() { }

Created dynamically and destroyed like this...

Animal** animalArray = new  Animal*[10];
animalArray[0] = new Dog(name, age);
animalArray[1] = new Cat(name, age);
animalArray[2] = new Owl(name, age);

delete[] animalArray;

and I am left wondering if an Animal object is created dynamically and then destroyed, will the _age and _name members get destroyed properly since the destructor for Animal class is empty? If so, why?

Thanks :D

like image 337
CookiePaw Avatar asked Oct 24 '25 21:10

CookiePaw


1 Answers

In the example you posted, you're actually not destroying everything correctly. In the line

delete[] animalArray;

you are deleting an array of Animal*s. Note that this does not automatically destroy the things being pointed to! You would have to do:

for(int i = 0; i < 3; ++i)
    delete animalArray[i];
delete[] animalArray;

This destroys each element, then destroys the container.

Now, your actual question is asking whether the private member variables are going to be cleanly destroyed. The answer is yes--after your destructor runs, any statically allocated variables' destructors will also be called by the compiler. It is their obligation to clean up after themselves. When you're doing polymorphism as in your example, the (empty) destructor Animal::~Animal will indeed be called.

Note that this carries the same warning as the code above: if you instead have

string* _name;

that you dynamically allocate in the constructor (with new), then the string* will be destroyed, but the pointed to string will not be. So in that case, you would have to manually call delete to properly clean up.

like image 100
George Hilliard Avatar answered Oct 26 '25 11:10

George Hilliard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!