在子类中填充静态类成员

时间:2017-08-04 00:11:53

标签: c++ c++11 static polymorphism

这是2个类,父类和子类:

class Model
{
    protected:
    static std::list<char *>   list;
}

class SubModel : public Model
{
    // Should add itself to Model::list...
}

所以,这里有2个示例类。我希望以每种子类(正确实现)将自己注册到static Model::list的方式创建通用模型。这样,任何其他子类都能够识别其他“现有”模型(和类型名称)。

我尝试了很多方法,但我不知道如何在许多其他文件中只填充一次静态成员。

任何想法,如果可能的话?

修改 我正在寻找一种方法在每个子模型中的某个地方做某些事情Model::list.push_back("SubModel");(当然还有相应的名称)

EDIT2: 显然,只有同一函数中的所有push_back都可行。我想要的是让子类自动注册自己。解决方法是创建一个包含register的虚拟static bool init(false);并注册该类。然后,设置为true,如果init为真,则构造函数将返回...

2 个答案:

答案 0 :(得分:3)

廉价的黑客技巧。对于每个子类构造函数中未使用的变量的开销,您可以确保注册每个类只运行一次。 static变量只初始化一次,因此调用初始化它的函数只调用一次。

#include <iostream>
#include <list>

class Model
{
public:
    static std::list<const char *>   list; // made public for ease of demonstration
                                           // const char * to store string literals
protected:
    // registration method
    bool reg(const char * name)
    {
        list.push_back(name);
        return true;
    }

};
std::list<const char *>   Model::list; // allocate storage for list


class SubModel1 : public Model
{
public:
    SubModel1()
    {
        // once will only be initialized once, so the reg method will only run once
        static bool once = reg("SubModel1");
        (void) once; // silence unused variable warning.
    }
};

class SubModel2 : public Model
{
public:
    SubModel2()
    {
        static bool once = reg("SubModel2");
        (void) once;
    }
};

class SubModel3 : public Model
{
public:
    SubModel3()
    {
        static bool once = reg("SubModel3");
        (void) once;
    }
};

int main()
{
    SubModel1 one;
    SubModel1 two;
    SubModel2 three;
    // note no SubModel3

    for (const char * model: Model::list)
    {
        std::cout << model << '\n';
    }
    return 0;
}

输出:

SubModel1
SubModel2

答案 1 :(得分:0)

class Model
{
protected:
    static std::vector<std::string> list;

};

// this line initializes 'list'
// this line must be outside the class 
std::vector<std::string> Model::list;

class SubModel : public Model
{
    // in the constructor, push the name of this class on to the vector:
    SubModel()
    {
       // you could check for duplicates first,
       // if you don't want the name to appear
       // multiple times (if you create multiple instances of this class)

       list.push_back("SubModel");
    }
};

class SubModel2 : public Model
{
    SubModel2()
    {
       list.push_back("SubModel2");
    }
};



int main()
{
    SubModel mod1;
    SubModel2 mod2;

    // list now contains two entries:
    // "SubModel"
    // "SubModel2"


}