C++ abstract base class constructors/destructors - general correctness

47,765

C++ does not allow for virtual constructors. A simple implementation (without the virtual constructor) would look something like this:

class ICommand {
public:
    virtual ~ICommand() = 0;
    virtual void callMe() = 0;
    virtual void callMe2() = 0;
};

ICommand::~ICommand() { } // all destructors must exist

Note that even a pure virtual destructor must be defined.

A concrete implementation would look exactly like your example:

class MyCommand : public ICommand {
public:
    virtual void callMe() { }
    virtual void callMe2() { }
};

You have a couple of options for the constructor. One option is to disable the default constructor for ICommand, so that subclasses will have to implement a constructor that calls your ICommand constructor:

#include <string>

class ICommand {
private:
    const std::string name;
    ICommand();
public:
    ICommand(const std::string& name) : name(name) { }
    virtual ~ICommand() = 0;
    virtual void callMe() = 0;
    virtual void callMe2() = 0;
};

ICommand::~ICommand() { } // all destructors must exist

A concrete implementation would now look something like this:

class MyCommand : public ICommand {
public:
    MyCommand(const std::string& name) : ICommand(name) { }
    virtual void callMe() { }
    virtual void callMe2() { }
};
Share:
47,765
Stuart Blackler
Author by

Stuart Blackler

I am a highly experienced lead software engineer, architect and proponent of clean coding. Currently, I am helping to disrupt the banking sector building high quality services and APIs. Over the past year, I have co-founded a local .Net developer meetup based in Bournemouth, contributed to various open source projects and investigated building my own programming language for educational purposes. Outside of work, I have a passion for improving myself physically and mentally. Physically, I enjoy climbing mountains or hiking through various cities in the world. I always aim to improve my mentally by reading personal development &amp; leadership books or through public speaking engagements.

Updated on September 15, 2020

Comments

  • Stuart Blackler
    Stuart Blackler over 3 years

    I would like to have a C++ Interface that must be overridden (if this is possible) when inherited. So far, I have the following:

    class ICommand{
    
    public:
        //  Virtual constructor. Needs to take a name as parameter
        //virtual ICommand(char*) =0;
        //  Virtual destructor, prevents memory leaks by forcing clean up on derived classes?
        //virtual ~ICommand() =0; 
        virtual void CallMe() =0;
        virtual void CallMe2() =0;
    };
    
    class MyCommand : public ICommand
    {
    public:
        // Is this correct?
        MyCommand(char* Name) { /* do stuff */ }
        virtual void CallMe() {}
        virtual void CallMe2() {}
    };
    

    I have purposely left how I think the constructor/destructor's should be implemented in ICommand. I know if I remove the comments, it will not compile. Please could someone:

    1. Show me how to declare the constructor/destructor's in ICommand and how they are meant to be used in MyCommand
    2. Have I set things up correctly in ICommand so that MyCommand must override CallMe and CallMe2.
  • Paul Manta
    Paul Manta over 12 years
    "C++ does not allow for virtual constructors" I'm not sure that's the right wording. What would a virtual constructor even mean, if some language were to implement it? (Note that I'm talking about actual constructors, not constructor-like functions, and am referring only to static languages.)
  • Filip Roséen - refp
    Filip Roséen - refp over 12 years
    @PaulManta Delphi has virtual constructors, which acts more like a factory but the type of the constructed object is decided during run-time (IIRC)
  • Mathias
    Mathias over 12 years
    I'm using the OP's definition of virtual constructor, which is more of a required function, similar to normal pure virtual member functions. In this case, something that forces subclasses to use a constructor that includes the "name" parameter. I agree that a "virtual constructor" technically doesn't make sense.
  • Stuart Golodetz
    Stuart Golodetz over 12 years
    @Paul: You might find this interesting: parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8
  • Paul Manta
    Paul Manta over 12 years
    @StuartGolodetz Notice that I excluded constructor-like functions in my original comment.
  • Stuart Golodetz
    Stuart Golodetz over 12 years
    @Paul: Apologies, read it quickly and just posted the first thing that popped to mind.