如何从随机子类创建对象
How to create object from random child class?
例如,我有基类A和子类B1、B2、B3等。
我想写一些类似的东西(或者用另一种方式来做这件事,这无关紧要(:
A *randomobject1;
randomobject1 = A::Getrandomobject();
randomobject1是指向随机子类中对象的指针。
我不知道怎么做!也许我需要存储对子方法的引用并在之后调用它,或者。。。我不明白。
我不需要真正的随机,我需要知道一些信息之前生成对象。
例如,子类包含带有一些整数的静态字段。我需要从包含这个整数的随机子类中生成对象,并且它>30(或者使用其他类型的字段(。因此,具有一些整数<30岁的人不会参与这一代。
我假设getRandomObject
函数中所有可能的子类都是已知的,并且您希望在每次调用中创建一个新实例。那么这就是一个可行的解决方案:
A *getRandomObject() {
int r = getRandomIntInRange(0, 3); // Some method returning a random int from [0,1,2]
switch (r) {
case 0: return new B1();
case 1: return new B2();
case 2: return new B3();
default: return NULL; // should never come here...
}
更新:
如果你的方法可能不知道所有可能的子类,那么注册机制可能是可行的,你可以在其中存储返回新实例(工厂(的类函数。
快速概述:
// Somewhere in your code
A *b1Factory() { return new B1(); }
A *b2Factory() { return new B2(); }
A *b3Factory() { return new B3(); }
// somewhere you have a factory list
typedef A* (*aSubclassFactoryFunc) (void);
std::vector<aSubclassFactoryFunc> factories;
A *getRandomObject() {
int r = getRandomIntInRange(0, factories.size()); // Some method returning a random int from [0,1,2,...,factories.size()]
return factories[r](); // Call random factory
}
新的子类只需向工厂列表中添加一个工厂方法。
更新2:
注册机制可以这样做:
#define REGISTER_A(B)
struct b_subclass_register_##B {
b_subclass_register_##B() {
registerASubclass(b_subclass_register_##B::create);
}
static A *create() { return new B; }
} dummy_instance_##B;
这是一个makro,它创建一个结构并在全局范围内创建一个伪实例。在其构造函数中,子类被注册。
你可以在你的子类CPP文件中使用它,比如:
REGISTER_A(B1);
这假设您事先知道所有子类。如果没有,您可以创建一个带有一些虚拟Clone
功能的原型注册系统。
为了创建对象,我只需要使用随机数生成器和结果上的switch
来确定要构造哪个类。为了处理回收内存,我返回一个std::unique_ptr
,这样客户端代码就不必担心删除指针了。
struct A {
//the random child class factory method
static std::unique_ptr<A> Getrandomobject();
//need a virtual destructor so that the child object is deleted properly
virtual ~A() =default;
private:
//random number generator
static std::mt19937 rng_;
//some state to check if the rng has been seeded
static bool inited_;
};
std::mt19937 A::rng_;
bool A::inited_ = false;
//our child classes
struct B1:A{};
struct B2:A{};
struct B3:A{};
struct B4:A{};
std::unique_ptr<A> A::Getrandomobject()
{
//seed rng if this is the first call
if (!inited_)
{
rng_.seed(std::random_device()());
inited_ = true;
}
std::uniform_int_distribution<std::mt19937::result_type> dist(0,3);
switch (dist(rng_))
{
case 0: return std::make_unique<B1>();
case 1: return std::make_unique<B2>();
case 2: return std::make_unique<B3>();
case 3: return std::make_unique<B4>();
default: return std::make_unique<B1>();
}
}
为了检查这是否确实给了我们一个随机子类,我们可以使用以下测试代码(由于typeid
,结果将取决于编译器(:
int main() {
auto randomobject1 = A::Getrandomobject();
cout << typeid(*(randomobject1.get())).name();
return 0;
}
#define MAX_CHILD_COUNT 3
A* A::GetRandomObject()
{
int _rand_index = rand()%MAX_CHILD_COUNT; // srand() before you call rand;
switch(_rand_index)
{
case 0:
return (new B1());
case 1:
return (new B2());
default:
return (new B3());
}
}
像这样?
相关文章:
- C++ 将子类的对象添加到父类的向量中
- 创建一个函数,该函数使用模板创建类或子类的对象
- 在C++中,友元类可以从友元类创建对象吗
- C++接口实现和子类化对象识别
- 为什么指向基类的指针可以指向子类的对象?
- 一般函数中类的概括为基类创建对象代码
- 当函数返回类型为父类时,如何返回子类的对象?
- 从 c++ 中的类创建对象
- 如何限制从特定类创建对象
- 如何在父类中生成子类的对象
- 如何在C++中从泛型类创建对象
- 如何从嵌套的 lambda 表达式函子类创建
- 使用 __declspec(dllexport) 从类创建对象
- 用于从工厂类创建对象名称的未定义引用
- 构造函数不能从抽象类创建对象
- 类创建对象与初始化技巧
- 为什么我们需要一个超类的指针指向子类的对象?
- 由子类创建的对象的c++重写函数
- 我无法使用我的类创建对象
- 如何从随机子类创建对象