Я заранее прошу прощения, поскольку я начинаю программировать OO.
У меня есть базовый класс Hero, с тремя производными классами Archer, Warrior и Mage. Пользователю предлагается выбрать один из них и создать объект соответствующего производного класса. Они имеют разные начальные значения и функции-члены, а следующий шаг - передать этот объект другой функции.
Скажем, функция называется 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?
}
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
так что адреса этих указателей на производные классы могут быть указаны базовым классом.
Нет, вам не нужно создавать 3 разных battle
задания, избегая этого, это как раз и цель наследования.
Вы можете создать единую battle
функцию:
void battle(Hero& hero)
{
}
Вы можете назвать это следующим образом:
battle(archer);
battle(mage);
battle(warrior);
но вам нужно будет создать Heros по - другому, потому что, как они создаются в настоящее время, они выпадают из сферы, как только if
или else
сделано.
Hero&
? Я не знаком с концепцией.
Здесь вы должны использовать полиморфизм во время выполнения.
Вместо создания локальных экземпляров объекта производного класса создайте указатель базового класса и укажите его на экземпляр производного класса:
Hero* hero = new Archer();
Hero* hero = new Mage();
Hero* hero = new Warrior();
Затем вы можете передать указатель базового класса Hero*
вашему методу battle
battle(hero)
Подпись вашего метода:
void battle(Hero* )
Это означает, что метод боя может принимать любого героя во время выполнения, будь то лучник, маг или воин.
#include
файл<memory>
.