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.

译:

最近遇到一个问题:有大量的子类继承自一个基类,且每个子类含有一个同类型数据的静态数据成员,但是各个子类的数据类型是不同的。我显然不能够把静态数据成员直接放到基类中,否则他会作为static数据成员被所有子类继承,而不是特定的子类。另外,拷贝和粘贴同样的静态成员声明到50多个类中总是让人感觉不爽。这里提供一个整洁的方案来解决这个问题:使用模板类来定义子类。

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:

译:这里是一个简单的例子来解析这个模式,使用了容易理解的名字定义Class 和 Class成员.

首先,一个简单的基类定义如下:

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:

译:紧接着我们定义模板类,它含有一个静态的列表,被每一个需要访问这个静态列表的子类访问,而不是所有的子类访问。

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: 

译:

现在我们可以使用模板基类来定义子类了,而不是使用Base基类。

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.

译:这个模式并不是特别的优雅,但是却非常实用的解决了我的问题:当我需要继承很多的子类来处理XML元素,而且需要管理具有特定的属性的XML子节点。