这是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为真,则构造函数将返回...
答案 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"
}