在C ++中,我有一个类Base
作为接口类和2个继承类:来自Base1
类的Base2
和Base
,如下所示:
class Base{
public:
virtual void printSomething() = 0;
// Some bla bla code...
};
class Base1 : public Base{
public:
Base1();
void printSomething();
};
class Base2 : public Base{
public:
Base2();
void printSomething();
};
以正常方式,在我的main.cpp中,我必须包含以下代码:
Base *b;
string base_name = "Base1"; // or "Base2"
if(base_name.compare("Base1") == 0){
b = new Base1();
}else{
b = new Base2();
}
所以,我想在上面使用Base *b = base_name()
代替if()else()
块。在c ++中,这是可能的,怎么样?谢谢!
答案 0 :(得分:6)
与Java不同,C ++不提供reflection概念的本机支持。您可以编写一个简单的函数来构造特定的Base
实例。这称为Factory:
Base* create_base_instance(string name) {
if (name == "Base1")
return new Base1();
if (name == "Base2")
return new Base2();
throw runtime_error("unknown class name");
}
Base *b;
string base_name = "Base1"; // or "Base2"
b = create_base_instance(base_name);
答案 1 :(得分:3)
简短的回答是否定的。答案很长:如果你想要一个惯用的解决方案,请查看Factory Method设计模式。
另一种方法:您可以通过地图中的字符串保持代理对象的键入,并使用该映射创建这些代理对象(并在需要时克隆它们)。此方法隐藏了最终用户的比较,并将其深入标准库容器中。
答案 2 :(得分:1)
使用std :: map实现工厂模式。
template<typename T>
struct Factory
{
static Base* Create()
{
return new T();
}
};
typedef std::map<std::string, Base* (*)()> FunMap;
FunMap fun;
void Register()
{
fun.insert(std::pair<std::string, Base*(*)()>("Derived1", Factory<Derived1>::Create));
fun.insert(std::pair<std::string, Base*(*)()>("Derived2", Factory<Derived2>::Create));
}
void CreateTypeDemo2(const std::string& name)
{
Base* bp = fun[name]();
bp->Name();
}
从main开始,你可以这样调用函数。
Register();
CreateTypeDemo2("Derived1");
CreateTypeDemo2("Derived2");
您甚至可以按照以下所示进行操作。在方法CreateDerived2
中,您可以使用不同的实现创建Derived2()而不是默认实现
Factory :: Create为我们提供了。
Base* CreateDerived2()
{
return new Derived2();
}
void Register()
{
fun.insert(std::pair<std::string, Base*(*)()>("Derived1",Factory<Derived1>::Create));
fun.insert(std::pair<std::string, Base*(*)()>("Derived2",CreateDerived2));
}
希望这会有所帮助。