随机类的宏

时间:2014-07-18 21:13:06

标签: c++ c-preprocessor

我有一个包含多个子类的父类,并且要添加一个生成并随机返回指向其中一个子类的指针的函数。例如,

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):
    ...
...

有没有办法使用预处理器做类似的事情?或者有没有办法在类声明之前或之后只运行一次方法? (如果我不仅可以为每个类增加一个计数器,而且还可以在单​​个映射中为它注册一个工厂,那将是很棒的。)或者,更一般地说,其他人如何处理这类问题?如果我的问题中的某些内容不清楚或需要改写,请告诉我。

1 个答案:

答案 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.