Search code examples
c++virtual-functions

Simulating a virtual static member of a class in c++?


Is there anyway to have a sort of virtual static member in C++?

For example:

class BaseClass {
    public:
        BaseClass(const string& name) : _name(name) {}
        string GetName() const { return _name; }
        virtual void UseClass() = 0;
    private:
        const string _name;
};


class DerivedClass : public BaseClass {
    public:
        DerivedClass() : BaseClass("DerivedClass") {}
        virtual void UseClass() { /* do something */ }
};

I know this example is trivial, but if I have a vector of complex data that is going to be always the same for all derived class but is needed to be accessed from base class methods?

class BaseClass {
    public:
        BaseClass() {}
        virtual string GetName() const = 0;
        virtual void UseClass() = 0;
};


class DerivedClass : public BaseClass {
    public:
        DerivedClass() {}
        virtual string GetName() const { return _name; }
        virtual void UseClass() { /* do something */ }
    private:
        static const string _name;
};

string DerivedClass::_name = "DerivedClass";

This solution does not satify me because I need reimplement the member _name and its accessor GetName() in every class. In my case I have several members that follows _name behavior and tenths of derived classes.

Any idea?


Solution

  • Here is one solution:

    struct BaseData
    {
      const string my_word;
      const int my_number;
    };
    
    class Base
    {
    public:
        Base(const BaseData* apBaseData)
        {
            mpBaseData = apBaseData;
        }
        const string getMyWord()
        {
            return mpBaseData->my_word;
        }
        int getMyNumber()
        {
            return mpBaseData->my_number;
        }
    private:
        const BaseData* mpBaseData;
    };
    
    class Derived : public Base
    {
    public:
        Derived() : Base(&sBaseData)
        {
        }
    private:
        static BaseData sBaseData;
    }
    
    BaseData Derived::BaseData = { "Foo", 42 };