C ++ - 使用类名作为函数参数

时间:2013-03-01 16:26:12

标签: c++ class function

假设我有名为ItemOne,ItemTwo,ItemThree和ItemFour的类列表,它们都是ItemBase的子类。

我想在另一个名为ItemGenerator的类中有一个构造函数,它接受任何这些类的名称。我该怎么做?

ItemGenerator *someItem = new ItemGenerator(ItemThree);

另一种选择是在其中一个类上传递静态函数,但同样,我不知道如何做到这一点。

ItemGenerator *someItem = new ItemGenerator(ItemOne::start());

感谢。

7 个答案:

答案 0 :(得分:1)

您可以使用模板:

struct ItemBase {virtual ~ItemBase();};
struct ItemOne : ItemBase {};
struct ItemTwo : ItemBase {};
struct ItemThree : ItemBase {};
struct ItemFour : ItemBase {};

struct ItemGeneratorBase {
    virtual unique_ptr<ItemBase> generate() {}
    virtual ~ItemGeneratorBase() {}
};
template<typename Item>
struct ItemGenerator : ItemGeneratorBase {
    virtual unique_ptr<ItemBase> generate() {
        return unique_ptr<ItemBase>(new Item());
    }
};

std::unique_ptr<ItemGeneratorBase> someItem(new ItemGenerator<ItemThree>());

答案 1 :(得分:0)

函数不能接受类的名称作为参数,因为类不是C ++中的对象。 但模板函数可以通过类名进行参数化。

这样的事情:

template<class T> 
ItemGenerator* ItemGeneratorFactory() { T::start(); ...}

ItemGenerator *someItem = ItemGeneratorFactory<ItemThree>();

答案 2 :(得分:0)

正如其他答案所示,您可以使用模板。

只是为了提供另一个想法,你可以传递一个函数指针来创建你想要的任何实例(或者你想用该类做什么)

ItemGenerator(ItemClassPtr itemClassFn)
{
    void * myObject = itemClassFn();
}

答案 3 :(得分:0)

我有点生疏,但我很确定你可以将ItemBase放在构造函数中,它会接受所有子类。

ItemGenerator::ItemGenerator(ItemBase base){\\do something with base
}

或者,如果它和使用模板不起作用,您可以创建多个构造函数:

ItemGenerator::ItemGenerator(ItemOne one){}
ItemGenerator::ItemGenerator(ItemTwo two){}
...

答案 4 :(得分:0)

你真的想传递名称,即字符串吗?然后你必须为Item * -classes提供相应的函数,例如

class ItemOne {
  static std::string name();
};

ItemGenerator *someItem = new ItemGenerator(ItemThree::name());

或者您在寻找模板吗?你有不同的可能性:创建一个类模板,可能是从ItemGenerator基类派生的:

class AbstractItemGenerator { /* ... */ };

template <class Item>
class ItemGenerator {
  ItemGenerator();
};

ItemGeneratorBase *someItem = new ItemGenerator<ItemTwo>();

或者只让构造者模板化 - 你不能明确指定参数,所以使用argumet推论:

//take 1: use pointers
class ItemGenerator {
  template <class Item>
  ItemGenerator(Item* dummy);
};

ItemGenerator *someItem = new ItemGenerator((ItemFour*)NULL);

//take 2: use a tag struct
template <class I>
struct ItemTag{};

class ItemGenerator {
  template <class Item>
  ItemGenerator(ItemTag<Item> tag);
};

ItemGenerator *someItem = new ItemGenerator(ItemTag<ItemOne>());

我不确定其中一个是否符合您的需求。也许详细说明你想用它来做什么。

答案 5 :(得分:0)

这正是Factory design pattern所做的。 基本上,ItemGenerator类中有一个静态方法可以返回指向ItemBase对象的指针,但是可以返回指向Item1,Item2等的指针,具体取决于静态方法的参数。

例如,在ItemGenerator类中,

static ItemBase *Generate( <any parameter> )
{
    switch (parameter)
    {
        case Value1: return new Item1();
        ...
        ...
     }
 }

答案 6 :(得分:0)

如果不了解ItemGenerator的目的,很难找到问题的解决方案。

正如Mankarse所说,一种解决方案是使用模板将您的类传递给生成器。

然而,如果ItemGenerator无法模板化或者您不想在此处使用模板,您仍然可以使用std :: function或boost :: function传递一个函数。

还有一些库可以帮助您为c ++添加反射。我记得CAMP,但我不知道它是否仍然有效。您可以在那里找到解决问题的方法。