Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VC10.0

Static Member of Derived Class

5.00/5 (1 vote)
6 Apr 2013CPOL1 min read 17.7K  
How to have a single declaration of a static member for derived classes, using a simple template

Introduction

Recently I had a situation where I had a large number of classes all derived from a single base class and wanted each derived class to have a static member of the same type, but with different values. I could obviously not put the static member in the base class otherwise it would be static to all derived classes, not each derived class. Also, the thought of copying and pasting the same static member declaration into 50 classes felt completely wrong. A neat solution is to use a template class to define the derived class.

Using the code 

Here is a quick example of the pattern, which probably has some name if someone feels like enlightening me :)

Firstly, a simple base class:

C++
class Base
{
public:
    virtual void doSomething() = 0;
};

And then we can define our template class, that is going to hold a static list of something that needs to be the same for each derived class, not all derived classes:

C++
template<typename T>
class DerivedTemplate : public Base
{
protected:
    static std::vector<int> listOfSomething;
};

template <typename _T>
std::vector<int> DerivedTemplate<_T>::listOfSomething;

Now we can write our derived classes, using this template as a base class, rather than the actual Base class: 

C++
class DerivedOne: public DerivedTemplate<DerivedOne>
{
public:
    DerivedOne()
    {
        if(listOfSomething.empty())
        {
            listOfSomething.push_back(1);
            listOfSomething.push_back(2);
        }
    };

    virtual void doSomething()
    {
        std::cout << "DerivedOne contains " << listOfSomething.size() << " items." << std::endl;
    };
};

class DerivedTwo: public DerivedTemplate<DerivedTwo>
{
public:
    DerivedTwo()
    {
        if(listOfSomething.empty())
        {
            listOfSomething.push_back(3);
            listOfSomething.push_back(4);
            listOfSomething.push_back(5);
        }
    };

    virtual void doSomething()
    {
        std::cout << "DerivedTwo contains " << listOfSomething.size() << " items." << std::endl;
    };
};

Nothing particularly clever, but quite useful in my situation, where I have a load of classes for processing XML elements and want a means of managing supported attributes on those elements.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)