Исправить список инициализаторов при наследовании от виртуального базового класса без создания проблемы с алмазом - PullRequest
0 голосов
/ 20 февраля 2020

Итак, я получаю, что когда вы создаете алмаз по наследству, наиболее производный класс должен явно вызвать конструктор подобъектов виртуального класса в своем списке инициализатора.

Но как насчет классов, которые наследуются от виртуальный класс без этого наследства создает сам бриллиант? например, Bow наследует от виртуального базового класса Weapon, нуждается ли Bow в вызове конструктора Object и в его списке инициализаторов и почему?

Я немного запутался со всеми наследованиями классов и списки инициализаторов, и мне просто нужно сначала разобраться, прежде чем продолжить, и удалить все ненужные вызовы из моих списков инициализаторов.

Конструктор объекта принимает sf :: Vector2f, который равен двум числам с плавающей запятой. До сих пор у меня были Виртуальные базовые классы: Подвижный, Оружие и Снаряд, поскольку они являются частью бриллианта.

enter image description here

// sf::Vector2f is an SFML data type which consists of two floats

class Object
{
private:
    sf::Vector2f m_pos;
public:
    Object(sf::Vector2f start_pos) {m_pos = start_pos;};
}

class Movable : virtual public Object
{
public:
    Movable(sf::Vector2f start_pos) : Object(start_pos) { ... };
}

class Weapon : virtual public Object
{
public:
    Weapon(float shotDelay, bool isStealth) : Object(sf::Vector2f(0,0)) { ... };
}

class Projectile : public Movable
{
public:
    Projectile (sf::Vector2f startPos, int damage) : Movable(startPos) { ... };
}

class Bow : public Weapon
{
public:
    Bow() : Weapon(BOW_SHOT_DELAY, BOW_STEALTH) { ... };
}

class Grenade : public Weapon, public Projectile
{
public:
    Grenade() : Weapon(GRENADE_SHOT_DELAY, GRENADE_STEALTH) {};//for Weapon
    Grenade(sf::Vector2f startPos) : Projectile(startPos, GRENADE_DAMAGE);//for Projectile
}

1 Ответ

0 голосов
/ 05 апреля 2020

Итак, после некоторого исследования, полезных комментариев, игры и исправления моего кода, я выяснил ответ и что пошло не так. Я предоставлял конструктору Object аргумент по умолчанию, поэтому он вызывался таким образом, независимо от того, включил я вызов в список инициализаторов класса или нет.

Класс, который наследуется от виртуального базового класса должен включать вызовы конструкторов дочерних объектов виртуального базового класса в своем списке инициализаторов, если у них нет конструкторов по умолчанию .

Так что в моем примере, поскольку Bow наследует от виртуального базового класса Weapon, который наследует от Объект, его список инициализатора будет выглядеть так:

Bow::Bow() : Object(BOW_STARTING_POS), Weapon(BOW_SHOT_DELAY, BOW_STEALTH)
{
  //constructor code
}

Для полноты я добавляю, какими должны быть списки инициализатора Grenade, когда нет конструктора по умолчанию:

Grenade::Grenade() : Object(GRENADE_STARTING_POS), Weapon(GRENADE_SHOT_DELAY, GRENADE_STEALTH)
{
  //weapon constructor code
}

Grenade::Grenade() : Object(GRENADE_STARTING_POS), Projectile(GRENADE_STARTING_POS, GRENADE_DAMAGE)
{
  // projectile constructor code
}

PS граната разделен на два конструктора, потому что мой дизайн требовал именно этого. В другом случае, когда вам нужен только один конструктор для класса, унаследованного от двух виртуальных базовых классов, один список инициализатора может содержать все вызовы конструктора как таковые:

Grenade::Grenade() : Object(GRENADE_STARTING_POS), Projectile(GRENADE_STARTING_POS, GRENADE_DAMAGE), Weapon(GRENADE_SHOT_DELAY, GRENADE_STEALTH)
{
  //constructor code
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...