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.