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

is there a way to call polymophism reflection in C++ like my code?

本文关键字:C++ 一样 调用 反射 我的 代码 有没有      更新时间:2023-10-16

在C++中,我将类Base作为接口类和 2 个继承类: 从Base类中Base1Base2如下:

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

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

简短的回答是否定的。长答案是:如果你想要一个惯用的解决方案,请查找工厂方法设计模式。

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

使用 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() 的实现,而不是默认的实现
工厂::创造给我们。

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

希望这有帮助。