2013-03-01 338 views
0

说我有名为ItemOne,ItemTwo,ItemThree和ItemFour,它们都是ItemBase的所有子类的类的列表。C++ - 使用类名称作为函数参数

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

ItemGenerator *someItem = new ItemGenerator(ItemThree); 

另一种选择是在这些类中的一个上传递一个静态函数,但是我不知道该怎么做。

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

谢谢。

+0

看看“工厂”的设计模式。 – Max 2013-03-01 16:28:39

+1

你究竟想达到什么目的?换句话说,'ItemGenerator'是用来处理类名还是'static'成员函数? – 2013-03-01 16:30:23

+0

这真的取决于你想如何使用构造函数中的类。你会得到大量不同的答案,它们会做出不同的假设,并得到不同的结果。 – 2013-03-01 16:40:14

回答

0

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

事情是这样的:

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

ItemGenerator *someItem = ItemGeneratorFactory<ItemThree>(); 
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>()); 
0

至于其他的答案表明,你可以使用模板实现。

只是提供另一种思路,你可以通过一个函数指针,创造任何你想要的一个实例(或者不管它是什么,你要与该类做)

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

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

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

或者,如果使用的模板不工作,你可以创建多个构造函数:

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

你真的想通过,即一个字符串?然后,你必须提供具有相应功能的Item * - 类,例如

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>(); 

或者只使construtor模板 - 你不能显式地指定参数,所以使用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>()); 

我不确定这些是否适合您的需求。也许要详细说明你想用什么。

0

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

例如,在ItemGenerator类,

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

这是很难找到一个解决问题的方法不知道的ItemGenerator目的。

由于Mankarse说,一个解决方案是使用模板类传递给发电机。

尽管如此,如果ItemGenerator不能被模板化,或者如果你不想在这里使用模板,你仍然可以像使用std :: function或boost :: function一样传递一个函数。

也有一些库可以帮助您将反射添加到C++中。我记得CAMP,但我不知道它是否仍然活跃。您可以在那里找到解决问题的方案。

相关问题