Karl Nicoll
Karl Nicoll

Reputation: 16419

Can I force a class to be inherited?

Consider the following class:

//! Counter class base. Must be inherited.
class base_seeded_counter
{
public:
    //! Destructor
    virtual ~base_seeded_counter() { };

    //! Get the next value.
    int get_next();

protected:
    //! Override the counter next value.
    void set_next(const int next);

private:
    int m_next_value;    // Next value.
}

// ------------------------------------------------------

inline int base_seeded_counter::get_next()
{
    return m_next_value++;
}

// ------------------------------------------------------

inline void base_seeded_counter::set_next(const int next)
{
    m_next_value = next;
}

The purpose of this class is to implement a base counter object with the intention that it must be inherited. It does not have any virtual methods other than the destructor and, more importantly, does not initialize the m_next_value member. This is the job of the derived class. For example:

class file_seeded_counter : public base_seeded_counter
{
public:
    file_seeded_counter(const std::string &file_name);

    void reseed();

private:
    std::string m_file_name;
}

inline int file_seeded_counter::file_seeded_counter(const std::string &file_name) :
    m_file_name(file_name)
{
    reseed();
}

inline void file_seeded_counter::reseed()
{
    int seed_from_file;

    // open file here and get seed value...

    set_next(seed_from_file);
}

This class, deriving from base_seeded_counter reads the initial counter value from a file, and offers the ability to re-read the seed from the file via the reseed() method. There may be other classes that offer similar functionality to seed from databases, network sources, or a PRNG, for example.

My question is this: Given that I have no pure virtual methods, does C++ offer a mechanism to prevent someone from creating an instance of base_seeded_counter?

Upvotes: 4

Views: 1533

Answers (2)

Jerry Coffin
Jerry Coffin

Reputation: 490108

Given that you already have a virtual destructor, the obvious way would be to declare it pure virtual. It's entirely legitimate to have a pure virtual destructor that's also defined in the base class:

class base_seeded_counter {
public:
    virtual ~base_seeded_counter() = 0;
    int get_next();
protected:
    void set_next(const int next);
private:
    int m_next_value;
}

inline virtual base_seeded_counter::~base_seeded_counter() {}

Defining the destructor this way doesn't change the fact that it's a pure virtual, so this class can't be instantiated.


As an aside, the comments you currently have in the code are 100% useless visual noise. A comment of get next on a function named get_next adds nothing useful at all.

Upvotes: 5

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

My question is this: Given that I have no pure virtual methods, does C++ offer a mechanism to prevent someone from creating an instance of base_seeded_counter?

Yes, give it a protected default constructor (may be empty).

Upvotes: 13

Related Questions