Странное поведение - PullRequest
0 голосов
/ 27 мая 2011

Кто-нибудь может объяснить вывод кода.

#include <iostream>

using namespace std;

class First {
        public:
                int a;
                First() {};
                First(int a) {
                        this->a = a;
                }

                int getA() {
                        return a;
                }

                virtual int getB() {
                        cout << "getB() from super class..." << endl;
                        return 0;
                }
};

class Second : public First {
        public:
                int b;
                Second(int b) {
                        this->b = b;
                }

                int getB() {
                        cout << "getB() from child class..." << endl;
                        return b;
                }

};

int main() {
        First* t = new Second(2);
        First* cTest = dynamic_cast<First*>(t);
        cout << cTest->getB() << endl;

}

Я ожидал, что метод суперкласса будет вызван из-за приведения к First.

спасибо заранее

Себастьян

Ответы [ 4 ]

4 голосов
/ 27 мая 2011

Функция getB() - это virtual в базовом классе, поэтому вы получаете производную реализацию независимо от того, есть ли у вас указатель на базу или указатель на производное.

(ЭтоЦелая цель полиморфизма.)

2 голосов
/ 27 мая 2011

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

Как правило, вам требуется только dynamic_cast () для перехода по иерархии наследования, а не вверх.

1 голос
/ 27 мая 2011

Существует только один объект, который имеет тип Второй.

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

First cTest = static_cast<First>(*t);
cout << cTest.getB() << endl;
0 голосов
/ 27 мая 2011

Вы ничего не меняете своим составом Вы применяете First * к First *, что является просто назначением. Поскольку t является Second с = new Second(2), вы переопределили виртуальную таблицу с записями дочернего элемента, поэтому она будет вызывать методы дочернего элемента, а не родителей.

cTest - это просто указатель на первый, который указывает на тот же объект, что и t, поскольку cTest и t содержат один и тот же адрес памяти, по которому существует второй объект, поэтому и вызывается метод Second.

...