Проблема переопределения виртуальной функции - PullRequest
3 голосов
/ 28 мая 2010

Хорошо, я пишу игру, в которой есть вектор класса pairent (врага), который будет заполнен детскими классами (goomba, koopa, boss1), и мне нужно сделать так, чтобы я вызывал update it называет дочерние классы соответствующим обновлением. Мне удалось создать пример моей проблемы.

#include <stdio.h>
class A{
    public:
        virtual void print(){printf("Hello from A");}
};

class B : public A{
    public:
        void print(){printf("Hello from B");}
};


int main(){
    A ab = B();
    ab.print();
    while(true){}
}

Требуется вывод: "Hello from B" Вывод получился: "Привет от А"

Как мне заставить его вызывать функцию печати B?

Ответы [ 3 ]

14 голосов
/ 28 мая 2010

Полиморфизм работает только на указатели и ссылки. Если вы присваиваете B для A, оно становится A, и вы теряете всю специфичную для B информацию, включая переопределения методов. Это называется "нарезка"; B части "отрезаются" от объекта, когда он назначается объекту родительского класса.

С другой стороны, если вы присваиваете B* для A*, оно выглядит как A*, но все еще действительно указывает на B, и поэтому 1016 * -специфическая информация остается, и виртуальные переопределения B будут использоваться.

Попробуйте:

int main(){
    A* ab = new B();
    ab->print();
    delete ab;
    while(true){}
}

То же самое относится и к присвоению B для A& (ссылка на A), например,

int main(){
    B b;
    A& ab = b;
    ab.print();
    while(true){}
}
3 голосов
/ 28 мая 2010

Ваше виртуальное ключевое слово размещено правильно, вам нужно использовать указатели или ссылки.

0 голосов
/ 28 мая 2010

Вам нужно вызвать метод обновления родителя перед любой обработкой классами-потомками:

struct Base_Class
{
  virtual void update(void)
  {
    cout << "Updating Base_Class.\n";
  }
};

struct Goomba : public Base_Class
{
  void update(void)
  {
     // Invoke the parent method first.
     Base_Class::update();

     // Perform Descendant operations
     cout << "Updating Goomba\n";
  }
};

Вот реализация:

#include <iostream>
using std::cout;

void Update_Player(Base_Class& b)
{
  b.update();
  return;
}

int main(void)
{
   Goomba g;
   g.update();

   Goomba g2;
   std::vector<Base_Class *> container;
   container.push_back(&g);
   container.push_back(&g2);

   std::vector<Goomba>::iterator iter;
   for (iter =  container.begin();
        iter != container.end();
        ++iter)
   {
       Update_Player(*(*iter));
   }

   return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...