Выделение стека объекта с помощью виртуальной функции приводит к непредсказуемому поведению (вызывает метод базового класса вместо дочернего класса) - PullRequest
0 голосов
/ 12 января 2020

У меня есть базовый c класс, который наследуется игроком унаследованного класса.

class Entity{
   public:
    virtual std::string getName(){ return "Hello World";}
 };

В моем расширенном классе я просто пытаюсь переопределить метод getName, как в следующем фрагменте:

  class Player : public Entity{
    public:
    std::string getName() override { return "Hello from Player"; }
  };

Когда я размещаю объект в куче, он вызывает правильный расширенный метод класса, я получаю вывод: «Hello from Player» объект выделения в куче делается так:

Entity* e= new Entity;
  Player* p = new Player;
  Entity* entity = p;
  std::cout << entity->getName() <<std::endl;

Но когда я выделяю то же самое объект в стеке, он вызывает базовый метод вместо переопределенного метода, я сделал выделение стека следующим образом:

Entity e1;
  Player p1;
  Entity entity1 = p1;
  std::cout << entity1.getName() <<std::endl;

Объединенный вывод всего кода выглядит следующим образом:

Hello от игрока -------------- Hello World

Я использую Clang версии 7.0.0-3 ~ ubuntu0.18.04.1 с c ++ 11 флаг, надеялся, сможет ли кто-нибудь объяснить мне это поведение. Разве распределение стека или кучи не должно влиять на поведение объекта? или я что-то упустил? Я пытался гуглить топи c, не получив точных соответствующих ответов Вот ссылка repl.it: https://repl.it/repls/GleefulDroopyRay

1 Ответ

1 голос
/ 12 января 2020

Это называется нарезка .

Когда вы делаете:

Entity entity1 = p1;

Вы вызываете конструктор копирования класса Entity и создаете фактический объект Entity, который является база. Таким образом, вызывается метод базы.

Если вы хотите иметь пример с объектами в стеке, вы можете выполнить одно из следующих действий:

Player p1;
Entity& entity1 = p1;
std::cout << entity1.getName() <<std::endl;

или

Player p1;
Entity* pEntity = &p1;
std::cout << pEntity->getName() <<std::endl;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...