Непонимание полиморфных функций

0

Я пытаюсь создать массив объектов, чей класс "наследует от базового класса. Поскольку я просто изучаю 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;
}
  • 0
    Какую книгу по С ++ вы используете? Это определенно кроется в этом.
Теги:
pointers
polymorphism

3 ответа

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

Вы близки, и вы, кажется, прекрасно разбираетесь в разрезе объектов. Тем не менее, фрагментация объектов здесь не происходит - функция вызывает себя, которая дает вам печаль.

Вы должны пометить свои функции-члены как virtual, чтобы воспользоваться полиморфизмом.

(Точнее, чтобы воспользоваться виртуальной отправкой.)


class A{
public:
    virtual int getNumber(){  // <--- 'virtual'!
        return(1);
    }
};
  • 0
    Спасибо, что исправляет мою проблему. Поскольку название этого раздела в настоящее время вводит в заблуждение тех, кто сталкивается с подобной проблемой, следует ли его переименовать / пометить заново?
  • 2
    @Giewev: мне было интересно об этом. Обычно я бы сказал «нет», но в этом случае изменение заголовка на то, что вы не получаете полиморфизм в вызовах функций, когда ожидаете этого, может быть лучше.
0

Программа getNumber 1 1 потому что функция getNumber не помечена как virtual. Без ключевого слова virtual, A* который указывает на B, не знает, чтобы просмотреть функцию в v-таблице. Так он просто вызывает функцию getNumber от A

Объявите функцию как

virtual int getNumber( );

и вы должны получить ожидаемое поведение.

Узнайте больше о виртуальных функциях и посмотрите на этот вопрос.

0

Здесь вы не испытываете обрезки объектов. Это пример скрытия функции.

В принципе, поскольку A и B имеют функцию getNumber, но это не виртуальная функция, нет никакой таблицы виртуальных функций, чтобы сообщить компилятору, какую функцию следует вызывать. Вместо этого он вызовет соответствующую функцию, основанную на типе (в данном случае A*).

getNumber как виртуальный в A, и это устраняет вашу проблему: virtual int getNumber() {... }

Ещё вопросы

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