有没有办法像我的代码一样调用C ++中的多态反射?

时间:2012-06-12 03:26:53

标签: c++ polymorphism

在C ++中,我有一个类Base作为接口类和2个继承类:来自Base1类的Base2Base,如下所示:

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 ++中,这是可能的,怎么样?谢谢!

3 个答案:

答案 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));
}

希望这会有所帮助。