【发布时间】:2013-10-02 21:46:04
【问题描述】:
我需要一种基于作为 std::string 传递的类名来实例化对象的方法。这现在有效,但需要概括:
void* create(std::string name) {
if(name == "classOne") return new ClassOne();
else if(name == "classTwo") return new ClassTwo();
/* ... */
}
我没有的东西:
- 对要实例化的类的控制:可以是 30 个方类。不得对此类进行任何更改(即基础祖先、多态创建者方法等...)
- 完整的类名列表:以后可能会添加更多类,并且不应对该工厂进行更改。
- 要实例化的类的包装器:作为前两点的结果。
其他的都可以。
最佳用例场景将是:
int main() {
void *obj = create("classTree"); // create object based on the string name
/* ... */
// once we know by context which specific class we are dealing with
ClassTree *ct = (ClassTree*)obj; // cast to appropiate class
std::cout << ct->getSomeText() << std::endl; // use object
}
作为一个侧面,也许是无关紧要的说明,考虑到要实例化的对象可能来自一个类或一个结构。
附加信息
我看到需要更多上下文。这是我的特定用例,经过简化:
// registration mechanism
int main() {
std::map< std::string, void(*func)(std::string, void*) > processors; // map of processors by class name
processors["ClassFour"] = (void(*)(std::string, void*)) &classFourMessageProcessor; // register processor (cast needed from specific to generic)
}
// function receiving string messages
void externalMessageHandler(std::string msg) {
std::string objType = extractTypeFromMessageHeader(msg); // extract type from message
// now that we know what we are dealing with, create the specific object
void *obj = create(objType); // << creator needed
processors[objType](msg, obj); // dispatch message to process
}
// previously registered message processor
void classFourMessageProcessor(std::String msg, ClassFour *obj) {
std::string streetAddress = msg.substr(10, 15); // knowing the kind of message we can extract information
obj->moveTheEtherTo(streetAddress); // use the created object
}
附加信息
我正在使用带有最新 GNU 编译器的 C++11。
【问题讨论】:
-
你不只是“一旦我们知道我们正在处理哪个特定类”就实例化正确的类,然后做你会用
void*做的事情? -
@Kal 在知道它是什么类之前,您可能需要使用
obj。 -
这不是正常的创建工厂的方式。由于 if 语句块很大,它不能很好地扩展。见stackoverflow.com/questions/5120768/…
-
我不认为您可以在不修改工厂代码本身的情况下允许将其他类型添加到您的工厂中。 C++ 缺乏运行时反射。例如,与 C# 不同。
-
返回
void*似乎是反 C++。你真的想至少返回一个指向某种抽象基类的指针。
标签: c++