简体   繁体   中英

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 ?

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.

If your coding standards allow using templates, you could write your factory method as:

template<typename T>
static unique_ptr<Warrior> createWarrior()
{
    return unique_ptr<Warrior> { new T{} };
}

And at the calling site, use:

unique_ptr<Warrior> archer1 = WarriorFactory::create<Archer>();
unique_ptr<Warrior> horseman1 = WarriorFactory::create<Horseman>();

etc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM