3

Projectile is a subclass of Node. I want the Projectile destructor to be called.

Note: In the real-life scenario, I have a list of Node* that are Projectile, Player or Enemy, each with their own destructor.

Node does not have a specified destructor in the .h file (I assume it uses the default one.)

    Node* p = new Projectile();
    delete(p); //Projectile destructor is never called
RainingChain
  • 6,347
  • 8
  • 28
  • 57
  • 1
    Possible duplicate of [When to use virtual destructors?](http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors) – LogicStuff Feb 03 '16 at 05:54
  • Do you mean that `Projectile` inherits from `Node` (if so, `super class` is the wrong term there to relate `Projectile` to `Node`)? – crashmstr Feb 03 '16 at 05:56
  • A default destructor is not virtual. If it isn't already, turn up the compiler warning level (-Wall should be enough for this in g++) and you'll see the compiler telling you that what you've written isn't going to work – user4581301 Feb 03 '16 at 06:03

4 Answers4

4

First, it seems pretty clear from your question that Projectile is a subclass of Node (see this Wikipedia entry).

If you have a class like Node that is built for subclassing, then you should ensure that its destructor is virtual:

class Node
{
...
    virtual ~Node();
};

This will cause the compiler to call the appropriate classs destructor when youdelete` a pointer to the superclass.

(A different question is whether it should be pure virtual.)

Ami Tavory
  • 66,807
  • 9
  • 114
  • 153
  • You know, I've never tried a pure virtual destructor. That's going in the queue for experimenting tomorrow. – user4581301 Feb 03 '16 at 06:01
  • Why aren't all functions always virtual? Is there an advantage to have them not virtual? – RainingChain Feb 03 '16 at 06:12
  • There are several reasons. One of them is that there is a runtime overhead associated with using them, and C++ philosophy is "pay only for the feature you're using". Bjarne Stroustrup has a book about these things; something like "The Design and Evolution of the C++ Language". – Ami Tavory Feb 03 '16 at 06:14
2

You have to make the destructor of Node to be virtual, the default one (non-virtual) doesn't satisfy the needs here, i.e. the dynamic polymorphism won't work.

class Node {
public:
    virtual ~Node() {}
}
songyuanyao
  • 147,421
  • 15
  • 261
  • 354
2

C++ is static type language, so from this statement Node* p = new Projectile(); compiler sees p as an object of Node. While destructing p, it will call destructor of class Node only.

To overcome this scenario, virtual comes into the picture.

Code:

class Node {
  public:
    virtual ~Node() {
      //delete resources allocated in Node class
    }
};

class Projectile : public Node {
  public:
    ~Projectile() {
       //delete resources allocated in Projectile class
     }
};
CreativeMind
  • 847
  • 6
  • 17
0

Short answer:

Make your destructor in Node virtual.

class Node {
  // Stuff...
  virtual ~Node();
};

Not-So-Short answer:

When Projectile and likes of that inherit Node, data members and functions are inherited from the Node. The derived class can override or replace the actual function definition in the parent class. This overriding happens at either Compile time or at the run time, depending on weather the function in the base class is declared 'virtual'.

In case of non-virtual destructor, the destructor to be called is determined by the type of pointer. So even though the pointer variable p is pointing to an instance of Projectile, delete(p) would call the destructor defined in Node.

In case of virtual destructor, the destructor to be called is determined at run-time. So, regardless of the pointer type, the destructor that gets called will be the one that is defined in the object pointed by p.

Ravi Shenoy
  • 477
  • 1
  • 4
  • 14