Karlovsky120 Karlovsky120 - 1 month ago 7
C++ Question

How to properly dispose of abstract members of an abstract class?

I have an abstract class like this:

class IMovable {
protected:
MovementPath *movementPath;

public:
IMovable();
virtual ~IMovable();
void setMovementPath(MovementPath *movementPath);
};


Where
movementPath
is an abstract class on it's own.

When concrete implementation of
IMovable
is deleted, I need to delete
movementPath
(more precisely it's concrete implementation at that point) along with any of it's members.

How do I do that?

I tried virtual destructors, but that didn't work (I might have messed something up) and deleting it in concrete implementations crashes the program which it should because it's wrong, blasphemous and should not be done there.

What do I do?

Answer

IMovable, as you have shown it, is not an abstract class, as it has no abstract methods of its own. Data members that are pointers to abstract types do not count.

In any case, to answer your question, MovementPath needs a virtual destructor, and then IMovable can call delete movementPath to invoke the correct concrete destructor, regardless of what type it actually is.

For example:

class MovementPath
{
...
public:
    virtual ~MovementPath() { ... }
...
};

class IMovable {
protected:
    MovementPath *movementPath;

public:
    IMovable() : movementPath(0) {}
    virtual ~IMovable() { delete movementPath; }

    void setMovementPath(MovementPath *newPath) {
        // whether or not you need to 'delete movementPath' here
        // depends on your particular requirements...
        movementPath = newPath;
    }
};

class MyMovementPath : public MovementPath
{
...
public:
    ~MyMovementPath() { ... }
...
};

class MyMovable : public IMovable
{
...
public:
    MyMovable() : IMovable() { ... }
    ~MyMovable() { ... }
...
};

MyMovementPath *path = new MyMovementPath;
MyMovable *movable = new MyMovable;
movable->setMovementPath(path);
...
delete movable; // <-- will delete the path as well...