Я пытаюсь создать массив объектов, чей класс "наследует от базового класса. Поскольку я просто изучаю C++ после использования Python, это была моя первая встреча с обрезкой объектов. Из того, что я прочитал, я должен использовать указатели на объекты вместо экземпляров самих объектов, но я не могу заставить его работать.
Например, почему эта программа выводит: 1 1 вместо: 1 2
#include <iostream>
class A{
public:
int getNumber(){
return(1);
}
};
class B : public A{
public:
int getNumber(){
return(2);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* list[2];
list[0] = new A();
list[1] = new B();
std::cout << list[0]->getNumber() << std::endl;
std::cout << list[1]->getNumber() << std::endl;
int x;
std::cin >> x;
return 0;
}
Вы близки, и вы, кажется, прекрасно разбираетесь в разрезе объектов. Тем не менее, фрагментация объектов здесь не происходит - функция вызывает себя, которая дает вам печаль.
Вы должны пометить свои функции-члены как virtual
, чтобы воспользоваться полиморфизмом.
(Точнее, чтобы воспользоваться виртуальной отправкой.)
class A{
public:
virtual int getNumber(){ // <--- 'virtual'!
return(1);
}
};
Программа getNumber
1 1
потому что функция getNumber
не помечена как virtual
. Без ключевого слова virtual
, A*
который указывает на B
, не знает, чтобы просмотреть функцию в v-таблице. Так он просто вызывает функцию getNumber
от A
Объявите функцию как
virtual int getNumber( );
и вы должны получить ожидаемое поведение.
Узнайте больше о виртуальных функциях и посмотрите на этот вопрос.
Здесь вы не испытываете обрезки объектов. Это пример скрытия функции.
В принципе, поскольку A
и B
имеют функцию getNumber
, но это не виртуальная функция, нет никакой таблицы виртуальных функций, чтобы сообщить компилятору, какую функцию следует вызывать. Вместо этого он вызовет соответствующую функцию, основанную на типе (в данном случае A*
).
getNumber
как виртуальный в A
, и это устраняет вашу проблему: virtual int getNumber() {... }