Есть такая проблема: имеется иерархия классов. В производных появляются новые методы. Есть массив указателей на базовый класс. Когда я создаю экземпляр производного класса и обращаюсь к нему через указатель базового, он пытается найти метод в базовом классе, который не существует.
Люди добрые, помогите, пожалуйста. Я пытался делать понижающее преобразование типа указателя с помощью dynamic_cast
:
MO[0] = dynamic_cast<hero*>(MO[0]);
Указатель вроде как меняет тип, но компилятор всё равно орёт
"[C++ Error] Main.cpp(230): E2316 'Move' is not a member of 'map_object'".
Вот важная часть кода:
class map_object {
int x,y, index;
public:
virtual void Draw()=0;
void set_x(int _x);
void set_y(int _y);
int get_x();
int get_y()y;
void set_index();
int get_index();
map_object(int _x, int _y);
};
map_object *MO[100];
class moving_object: public map_object {
public:
virtual void Move(int _d);
moving_object(int _x, int _y):map_object(_x, _y);
};
class creature: public moving_object {
int health;
void Death();
public:
void cure(int _health);
void damage(int _damage);
int get_health();
creature(int _x, int _y, int _health):moving_object(_x, _y);
};
class mage: public creature {
int mana;
public:
void mana_fill(int _mana);
void mana_reduce(int _mana);
int get_mana();
mage(int _x, int _y, int _health, int _mana):creature(_x, _y, _health);
};
class hero: public mage {
public:
void Draw();
hero(int _x, int _y, int _health, int _mana):mage(_x, _y, _health, _mana);
};
void __fastcall TfrmMain::FormKeyPress(TObject *Sender, char &Key) {
switch (Key) {
case 'w': {MO[0]->Move(0); break;}
case 'd': {MO[0]->Move(1); break;}
case 's': {MO[0]->Move(2); break;}
case 'a': {MO[0]->Move(3); break;}
}
}
Попробуйте посмотреть на ваш код глазами компилятора. Вы объявили MO
как массив указателей на объекты класса map_object
, в котором метода Move
нет. Вы присвоили его элементам значения через dynamic_cast
к hero
- наследнику map_object
. Чего вы этим добились? А ничего. MO
как был массивом указателей на map_object
, так им и остался. Компилятору, в общем-то, всё равно, каких наследников map_object
'а вы присваиваете MO
, при обращении по этому указателю он всегда будет видеть только те поля и методы, которые объявлены в map_object
. Если вы хотите вызывать методы наследников по указателю на их предка, необходимо привести указатель на предка к указателю на наследника. Именно здесь и нужно*
использовать понижающее преобразование:
dynamic_cast<hero*>(MO[0])->Move(0);
*
На самом деле не нужно. Если ваша иерархия классов подразумевает принудительные понижающие преобразования, то скорее всего это плохая иерархия. В вашей иерархии теряется весь смысл наследования - вынесение общего для нескольких классов функционала в базовый класс и уменьшение свяности (coupling) вашего приложения. К тому же есть ненулевая вероятность, что однажды вы сделаете понижающее преобразование объекта из другой ветки иерархии, что приведёт к вылету программы.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Программа должна выводить, сколько раз каждое слово встречается в строке, но этого не происходитВот код:
Как реализовать программу, которая бы получала на вход изображение, изменяла его, а потом сохраняла новый вариант куда-нибудь в другое место?
Здравствуйте все, кто читает это! Интересует такой вопрос: Как разбить изображение на пиксели и обработать каждый из них? Или как получить...