Search code examples
c++factory

How can I return unique_ptr from factory method?


I have a few classes with heroes that are extended from abstract class Warrior:

enum Warrior_ID { Infantryman_ID=0, Archer_ID, Horseman_ID };

class Warrior
{
  public:
    virtual void info() = 0;
    virtual ~Warrior() { }
    static unique_ptr<Warrior> createWarrior( Warrior_ID id );
};

class Infantryman: public Warrior
{
  public:
    void info()
    {
      cout << "Infantryman" << endl;
    }
};

class Archer: public Warrior
{
  public:
    void info()
    {
      cout << "Archer" << endl;
    }
};

class Horseman: public Warrior
{
  public:
    void info()
    {
      cout << "Horseman" << endl;
    }
};

And this is my factory method, that returns specific character:

unique_ptr<Warrior> Warrior::createWarrior( Warrior_ID id )
{
    unique_ptr<Warrior> p;
    switch (id)
    {
        case Infantryman_ID:
            p = new Infantryman(); //this doesn't work
            break;
        case Archer_ID:
            p = new Archer(); //this doesn't work
            break;
        case Horseman_ID:
            p = new Horseman(); //this doesn't work
            break;
        default:
    }
   return p;
};

How can I return unique_ptr with specific character without using make_unique ?


Solution

  • std::unique_ptr's pointer constructor is explicit, so you need

    p = std::unique_ptr<Warrior>{new Infantryman{}};
    

    Alternatively, use the reset() member function:

    p.reset(new Infantryman{});
    

    As noted in comments, you don't really need to declare a local variable p and then modify it. You can return directly from the switch block:

        case Infantryman_ID:
            return std::unique_ptr<Warrior>{new Infantryman{}};
        case Archer_ID:
            return std::unique_ptr<Warrior>{new Archer{}};
    

    and so on.