В C ++, как можно использовать член класса, который будет содержать любой объект, производный от базового класса?

0

Заранее благодарим за чтение и/или реагирование на это. Я новичок в программировании.

Скажем, у меня был класс Player, который использовал объект оружия типа ABC в качестве члена.

class Player
{
private:
Weapon * mainHand;  // I think this is what I want?
};

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

Во всяком случае, я пробовал около 2 недель, чтобы понять это, прочитав материал на форумах, и я просто потерпел неудачу. Спасибо, что помогли мне.

  • 0
    Как бы вы присвоили оружие, если оно не должно было быть получено? Вы также можете показать свою лучшую "неудачную" попытку?
  • 0
    Может быть, вы можете показать, что вы пытались, и объяснить, как это не удалось?
Показать ещё 1 комментарий
Теги:
pointers
polymorphism

4 ответа

1
Лучший ответ

Вы можете просто назначить переменной mainHand указателю на любой объект типа, производный от класса Weapon. Подобно этому (просто пример, а не предложение):

void equipClub()
{
    Club* someShinyClub = new Club();
    mainHand = someShinyClub;
}

или даже напрямую:

mainHand = new Club();

После этого все методы, объявленные оружием, будут доступны из этого указателя. Но для конкретных операций с производными классами вам понадобится бросок.

  • 0
    Добавление equipWhatever() для каждого типа оружия не является расширяемым.
  • 0
    Конечно нет. Я специально указал, что это не дизайнерское предложение.
Показать ещё 1 комментарий
0

См. Ниже пример. Пожалуйста, примите в соответствии с вашими потребностями.

class Weapon
{
public:
    virtual void fire()=0;
};

class Gun:public Weapon
{
public:
    void fire()override
    {
        std::cout<<"Gun\n";
    }
};

class Rifle:public Weapon
{
public:
    void fire()override
    {
        std::cout<<"Rifle\n";
    }
};

class Player
{
public:
    Player(Weapon* weapon):mainHand(weapon)
    {
    }
    void fire()
    {
        mainHand->fire();
    }
private:
Weapon * mainHand;  // I think this is what I want?
};
int _tmain(int argc, _TCHAR* argv[])
{
    Gun gun;
    Rifle rifle;
    Player p1(&gun);
    Player p2(&rifle);
    p1.fire();
    p2.fire();
}
  • 0
    Круто, спасибо! Определенно дает мне несколько новых идей.
0

Если я правильно понимаю, вы хотите решить выбор оружия у Игрока во время выполнения.

Вероятно, вам известно о том, что для этого вам нужны производные классы из Weapon.

Вы просто можете сделать следующее: хотя я рекомендую вам найти более эффективный способ. (Классы Dagger и Sword)

if(player.weaponchoice == "dagger") //assuming that the player will decide the weapon choice.
{
   player.mainHand = new Dagger();
} 
else if(player.weaponchoice == "sword")
{
   player.mainHand = new Sword();
}
  • 0
    Отлично, спасибо!
0

Ссылка на оружие может быть назначена любому объекту, который расширяет Оружие. Итак, если клуб расширяет Оружие, вы можете написать:

this->mainHand = new Club();

mainHand может вызвать только общедоступные и защищенные методы в классе Weapon.

this->mainHand->fire();

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

((Club *) this->mainHand)->beatToDeath(); 
  • 0
    Очевидно, я понятия не имел, как правильно использовать -> до сих пор. Большое спасибо за комментарий!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню