виртуальная таблица с различными типами параметров

class Base {
public:
virtual void f(float) { cout << "Base::f(float)\n"; }
};

class Derived : public Base {
public:
virtual void f(int) { cout << "Derived::f(int)\n"; }
};

int main() {
Derived *d = new Derived();
Base *b = d;
b->f(3.14F);
d->f(3.14F);
}

Насколько я понимаю, виртуальная таблица класса Derived:

+-----------------+
| Base::f(float)  |
+-----------------+
| Derived::f(int) |
+-----------------+

Тем не менее, эта программа выводит:

Base::f(float)
Derived::f(int)

Почему эти два дают разные результаты? я думал b а также d должен указывать на ту же виртуальную таблицу.

0

Решение

Это на самом деле не имеет ничего общего с vtables. Derived::f делает не переопределение Base::f в этом случае он объявляет новую функцию, которая скрывает Base::f,

Ты можешь позвонить Base::f на Derived экземпляр напрямую с помощью квалифицированного вызова:

d->Base::f(3.14F);

Или вы можете выставить Base::f с using директива:

class Derived : public Base {
public:
using Base::f;
virtual void f(int) { cout << "Derived::f(int)\n"; }
};

С using директива, оба int а также float Будут рассмотрены версии:

d->f(3.14F); //calls Base::f
d->f(3);     //calls Derived::f

C ++ 11 представил override спецификатор, чтобы помочь диагностировать проблемы, такие как это. Если вы сделаете следующее изменение:

 void f(int) override { cout << "Derived::f(int)\n"; }

тогда g ++ выдает следующую ошибку:

main.cpp:12:18: error:
'virtual void Derived::f(int)' marked 'override', but does not override
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]