【问题标题】:C++ Choose a random object at runtime [duplicate]C ++在运行时选择一个随机对象[重复]
【发布时间】:2018-07-03 00:34:44
【问题描述】:

我想选择一个随机类,并在运行时创建它的一个对象(我选择的类是从基类派生的)。我如何做到这一点

【问题讨论】:

  • 不,您不能创建定义数组。
  • ABC 是否继承自公共基类?
  • 这是一个很糟糕的问题。这是XY Problem的典型案例。
  • @NathanOliver 是的,它们继承自一个通用基类
  • 你不能做类似Base *ptr; switch (rand()%3) {case 0: ptr = new A; break; case 1: ptr = new B; break; case 2: ptr = new C;}的事情吗? (或者更好的是,使用unique_ptrs 而不是普通指针。)

标签: c++


【解决方案1】:

使用工厂函数:每个类都应提供具有相同签名的静态函数,该函数返回指向基类的指针。然后,构建一个具有相同签名的工厂函数的数组,以便您可以随机选择。

#include <memory>
#include <vector>
#include <random>

class CommonClass
{
public:
    typedef std::shared_ptr<CommonClass> (*FactoryFunction)(); // type for factory function
};

class A : public CommonClass
{
public:
    A() {};
    static std::shared_ptr<CommonClass> Create() { return std::make_shared<A>(); }
};

class B : public CommonClass
{
public:
    B() {};
    static std::shared_ptr<CommonClass> Create() { return std::make_shared<B>(); }
};


std::shared_ptr<CommonClass> CreateRandom()
{
    // Vector of factory functions, initialized once.
    static std::vector< CommonClass::FactoryFunction >  factories = 
        { &A::Create, &B::Create };

    std::random_device rd;
    std::uniform_int_distribution<> dis(0, 1);

    // Generate random index, look up factory function, then call it
    return factories[dis(rd)]();
}

int main()
{
    std::shared_ptr<CommonClass> c(CreateRandom());
}

评论者提出了一个很好的观点。这是使用 CRTP 编写一次工厂函数的顶部部分的替代版本:

// Interface layer
class CommonClass
{
public:
    typedef std::shared_ptr<CommonClass> (*FactoryFunction)();
};

// CRTP layer.  Put any subclass implementation here that can be expressed
// as a compile-time expression of the type of the subclass.
template<class S>
class CommonClassImpl : public CommonClass
{
public:
    static std::shared_ptr<CommonClass> Create() { return std::make_shared<S>(); }
};


class A : public CommonClassImpl<A>
{
public:
    A() {};
};


class B : public CommonClassImpl<B>
{
public:
    B() {};
};

【讨论】:

  • 您可以通过在子类(CRTP)上模板化CommonClass 来减少重复
猜你喜欢
  • 1970-01-01
  • 2015-07-15
  • 2015-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多