0
class Person
{
public:
    Person(std::string& name,long id) : name_(name), id_(id) {}
    ~Person() {}
private:
    std::string& name_;
    long id_;
};

class Student : public Person
{
public:
    Student(std::string& name, long id) : Person(name,id) {}
    Student(std::string& name, long id, const std::vector<int*>& courses) : Person(name,id), courses_(courses) {}
    virtual ~Student() {
        std::vector<int*>::iterator it;
        for (it = courses_.begin(); it != courses_.end(); ++it)
        delete (*it);
    }
    const std::vector<int*>& getCourses() const { return courses_; }
private:
    std::vector<int*> courses_;
};

int main(){
    std::string name("Rina");
    std::vector<int*> courses;
    courses.push_back(new int(1345));
    Person* p = new Student(name,37,courses);
    Student* s = (Student*)p;
    std::cout << (*(s->getCourses().at(0)));
    delete p;
}

I understand that the

delete p;

makes us realize the problem that

~Person()

is not virtual. My question is: why should

~Person() 

be virtual?

TheNotMe
  • 1,048
  • 2
  • 17
  • 33

2 Answers2

2

For the same reason that you make other methods virtual.

Person *p;
...

delete p;

wouldn't handle subclasses of Person properly if the destructor wasn't virtual. i.e. it would simply invoke the Person component and not the subclass component (e.g. Employee)

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
1

Because that's what the standard says. delete p; is undefined behavior otherwise.

5.3.5 Delete [expr.delete]

3) In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.

The reason it's like that is probably for it to be able to handle calling derived class destructors (like calling virtual functions) without adding overhead to classes that don't require it (i.e. don't make all classes polymorphic by introducing a virtual destructor by default just to handle this particular case).

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625