2

在 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++ 中,这可能吗,如何?谢谢!

4

3 回答 3

6

与 Java 不同,C++ 不提供对反射概念的本机支持。您可以编写一个简单的函数来构造特定的Base实例。这称为工厂

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);
于 2012-06-12T03:32:42.613 回答
3

最简洁的答案是不。长答案是:如果您想要一个惯用的解决方案,请查看工厂方法设计模式。

另一种方法:您可以在映射中保留由字符串键入的代理对象,并使用该映射来创建这些代理对象(并在需要时克隆它们)。此方法对最终用户隐藏比较并将其推入标准库容器的深处。

于 2012-06-12T03:32:49.717 回答
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));
}

希望这可以帮助。

于 2012-06-12T06:46:28.393 回答