Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中,是否可以基于给定标识符创建基类的新实例,反之亦然+;_C++ - Fatal编程技术网

C++ 在C+中,是否可以基于给定标识符创建基类的新实例,反之亦然+;

C++ 在C+中,是否可以基于给定标识符创建基类的新实例,反之亦然+;,c++,C++,我有一个基类和多个子类来扩展它。我的目标是基于C++创建一个子类的新实例,反之亦然。我使用了如下的switch case语句: std::shared_ptr<base> create(int id) { std::shared_ptr<base> p; switch (id) { case 0: p = std::make_shared<derived1>(); break; case 1:

我有一个基类和多个子类来扩展它。我的目标是基于C++创建一个子类的新实例,反之亦然。我使用了如下的switch case语句:

std::shared_ptr<base> create(int id)
{
    std::shared_ptr<base> p;
    switch (id) {
    case 0:
        p = std::make_shared<derived1>();
        break;

    case 1:
        p = std::make_shared<derived2>();
        break;

    default:
        throw;
    }

    return p;
}
std::共享ptr创建(int-id)
{
std::共享的ptr p;
开关(id){
案例0:
p=std::使_共享();
打破
案例1:
p=std::使_共享();
打破
违约:
投掷;
}
返回p;
}
但我想要一个更优雅的方法,反之亦然。 下面是我用Java编写的目标的一个工作实现:

static BiMap<Integer, Class<? extends Base>> map = HashBiMap.create();

static {
    map.put(0, Derived1.class);
    map.put(1, Derived2.class);
}

static Base createInstance(int id) throws IllegalAccessException, InstantiationException {
    return map.get(id).newInstance();
}

static int getId(Base instance) {
    return map.inverse().get(instance.getClass());
}

静态BiMap我会有一个虚拟函数,名为
\u getId()
。然后可以让每个派生类返回其唯一标识符:

class base {
    ...
    virtual int _getId() = 0;
};

class derived1: public base {
    ...
    int _getId() { return 1; }
};

...
因此,您的静态基
getId()
可能如下所示:

static int getId(base *instance) {
    return instance->_getId();
}

C++不像Java那样有元类。所以java代码中最接近的C++等价物看起来就是这样的:

std::shared_ptr<base> create(int id)
{
    std::shared_ptr<base> p;
    switch (id) {
    case 0:
        p = std::make_shared<derived1>();
        break;

    case 1:
        p = std::make_shared<derived2>();
        break;

    default:
        throw;
    }

    return p;
}
#包括
#包括
阶级基础
{
公众:
...
虚拟int getId()常量=0;
};
类Derived1:公共基
{
公众:
...
int getId()常量重写{return 0;}
};
派生类2:公共基
{
公众:
...
int getId()常量重写{return 1;}
};
...
使用createFunc=std::shared_ptr(*));
静态std::map myMap
{
{0,[]()->std::shared_ptr{return std::make_shared();},
{1,[]()->std::shared_ptr{return std::make_shared();}
...
};
静态std::shared_ptr createInstance(int id)
{
自动iter=myMap.find(id);
if(iter==myMap.end())
扔。。。;
返回iter->second();
}
静态int getId(基本*实例)
//或:静态int getId(std::shared_ptr&instance)
{
返回实例->getId();
}

可能是std::map之类的东西?一个映射,其中一个整数作为键,一个函数指针返回一个共享的_指针。可执行,但不是特别方便。C++缺乏反射,这让你很难受。另请参见工厂设计模式。@user4581301@MooingDuck这只解决了用户问题的一半。它根本没有解决如何实现
create(id)
。@Remy看起来OP已经有了一个有效的
create()
方法,不是吗?@scohe001他们有,但他们不喜欢它,想用一个映射来代替它。在这种情况下,数组会比
std::map
快得多。@MooingDuck在这个特定的例子中,是的。但谁又能说OP将来可能会希望动态注册这些类,比如我将实现移动到单独的单元中。不能使用固定数组(当然可以,但必须限制可以注册的最大类数)