我提前道歉,因为我是OO编程的初学者。
我有一个名为Hero的基类,有三个派生类Archer,Warrior和Mage。提示用户选择其中一个,并创建适当的派生类的对象。它们具有不同的初始值和成员函数,下一步是将此对象传递给另一个函数。
让我们说这个函数叫做battle(),它将对象作为参数。我该怎么做呢?我是否必须创建三个单独的battle()或者是否有一种方法来传递对象而无需指定派生类?
void Hero::init(string job)
{
if (job == "archer")
Archer archer;
else if (job == "mage")
Mage mage;
else
Warrior warrior;
battle(); // What to put as argument?
}
答案 0 :(得分:3)
不,您不必创建3个不同的battle
函数,避免这正是继承的目的。
您可以创建一个battle
功能:
void battle(Hero& hero)
{
}
您可以按如下方式调用它:
battle(archer);
battle(mage);
battle(warrior);
但您需要以其他方式创建自己的英雄,因为现在创建它们时,只要if
或else
完成就会超出范围。
答案 1 :(得分:3)
battle()
应该将基类的引用或(智能)指针作为参数。例如:
void battle(std::shared_ptr<Hero> ptr);
你的论点也应该是一个聪明的指针:
void Hero::init(const std::string& job)
{
std::shared_ptr<Hero> ptr;
if (job == "archer")
ptr = std::make_shared<Archer>();
else if (job == "mage")
ptr = std::make_shared<Mage>();
else
ptr = std::make_shared<Warrior>();
battle(ptr);
}
std::shared_ptr
是一个智能指针类,它封装了指针的动态内存分配和资源获取。这样我们就不必在每个地方写new
。此外,当智能指针被销毁时(意味着不再存在ptr
的副本,如果有的话),则在包含的delete
指针上调用Hero
。
上述方法有效,因为所有三个类都派生自Hero
,因此基类可以指向这些派生类指针的地址。
答案 2 :(得分:2)
这是你应该使用运行时多态性的地方 不是创建本地派生类对象实例,而是创建基类指针并将其指向派生类实例:
Hero* hero = new Archer();
Hero* hero = new Mage();
Hero* hero = new Warrior();
然后,您可以将基类指针Hero*
传递给方法battle
battle(hero)
您的方法的签名将是:
void battle(Hero* )
这意味着,战斗方法可以在运行时接受任何类型的英雄,无论是弓箭手,法师还是战士。