0

I know you shouldn't call any virtual function in the ctor or dtor of the base class, but what about from that of the most derived class? Should be fine right? E.g.

class base {
    ...
    virtual void free() = 0;
};
class child : public base {
    ...
    free() {/* free memory */}
    ~child() {free();}
};
mchen
  • 9,808
  • 17
  • 72
  • 125
  • 6
    don't call virtual methods in constructors or destructors. – Luchian Grigore May 13 '13 at 20:07
  • 2
    If you care calling from the most derived class, it will be fine, but you are not gaining anything from it being virtual since you know what is being called. If you end up being not the most derived class (and the derived class overrides your method) then this destructor will fail. TL;DR - don't call virtual methods in c'tors/d'tors – T. Kiley May 13 '13 at 20:09
  • 1
    @ShaflikYaghmour - yes, but we're talking *pure* virtual being called from the derived class. Surely there is no ambiguity as the derived class holds the *only* implementation of the function. – mchen May 13 '13 at 20:09
  • possible duplicate of [Calling virtual functions inside constructors](http://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors) – Shafik Yaghmour May 13 '13 at 20:11
  • So what are you gaining by calling it virtually? You are just introducing an overhead as it has to look the function up (unless the compiler optimises this, which I doubt as you're not meant to call them from c'tors/d'tors anyway). – T. Kiley May 13 '13 at 20:11
  • @T.Kiley - thanks. Yes, I do know exactly what is being called but the base uses a virtual function to enforce an interface in derived classes. – mchen May 13 '13 at 20:11
  • Ah I see, for clarity and in case of further derivation, I would call Child::free() so is clear you meant to call that derivation and not the virtual implementation. – T. Kiley May 13 '13 at 20:17
  • Are you really sure that there will never ever be a class derived from `child`? Usually you are not. – Gorpik May 13 '13 at 20:20

2 Answers2

7

Well, you can do it, but the dynamic type of *this inside child::~child() is child, and not anything more derived. So when you have a further derived class class foo : child which overrides free(), then the overridden function will not be called.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

There's nothing wrong with calling a virtual function from a constructor or destructor, base class or otherwise. But you have to know what it does: the dynamic type is the class being constructed or destroyed, so it won't call an override in a class derived from the one that's being constructed or destroyed. In particular, if the function is pure virtual, you won't get an override, and the behavior is undefined. So a good rule is "don't call pure virtual functions from constructors or destructors. In your example, class::free is not pure virtual, so there's no problem calling it.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165