我有一个包含多个子类的父类,并且要添加一个生成并随机返回指向其中一个子类的指针的函数。例如,
class Parent { ... }
class Child1 : public Parent {...}
class Child2 : public Parent {...}
...
class ChildN : public Parent {...}
// returns one of the children, randomly
Parent* generate_random();
一方面,我可以编写generate_random
硬编码子类的数量,并在每次添加Parent的新子类或删除旧的子类时更新此数字。但这似乎有点脆弱。同样,我甚至可以使用const变量来跟踪子类的数量。同样,每当添加和删除类时,我都必须手动更新。这似乎也很脆弱。
相比之下,在像Python这样的语言中,我可能会将装饰器放在Parent的每个子类的声明之上,这会增加所有子类的计数并使用它。例如:
_num_subclasses = 0
def _register_subclass(cls):
global _num_subclasses
_num_subclasses += 1
class Parent(object):
...
@_register_subclass
class Child1 (Parent):
...
@_register_subclass
class Child2 (Parent):
...
...
有没有办法使用预处理器做类似的事情?或者有没有办法在类声明之前或之后只运行一次方法? (如果我不仅可以为每个类增加一个计数器,而且还可以在单个映射中为它注册一个工厂,那将是很棒的。)或者,更一般地说,其他人如何处理这类问题?如果我的问题中的某些内容不清楚或需要改写,请告诉我。
答案 0 :(得分:1)
我对python一无所知,但让我们检查一下:
_num_subclasses = 0
def _register_subclass(cls):
global _num_subclasses
_num_subclasses += 1
@_register_subclass
class Child1 (Parent):
将其转换为C ++(ish)
int _num_subclasses = 0;
template<class cls>
bool _register_subclass() {
_num_subclasses += 1;
return true;
}
class Child1 : public Parent {
};
static const bool register1 = _register_subclass<Child1>();
然而,通常需要一个类型列表。通常模糊地这样:
typedef std::unique_ptr<Parent*> ParentPointer;
//an enum is recommended, but type_id can work, depending on what you're doing
std::unordered_map<std::type_info, std::function<ParentPointer()>> _subclass_generator;
template<class cls>
bool _register_subclass() {
_subclass_generator[typeid(cls)] =
[]()->ParentPointer{
return ParentPointer(new cls{});
};
return true;
}
class Child1 : public Parent {
};
static const bool register1 = _register_subclass<Child1>();
然后你可以使用_subclass_generator
int selection = std::rand() % _subclass_generator.size();
auto& generator = *std::advance(_subclass_generator.begin(), selection);
ParentPointer ptr = generator(); //generates a Child.