Компилятор: GCC
В приведенном ниже коде все 3 подписи Foo () были Foo(bool b)
, но кто-то обновил код и забыл изменить DeriveB::Foo
, Это проходит компиляцию. Как мы можем предотвратить подобные ошибки?
class Base {
virtual Foo(bool b, int i);
}
class DerivedA : public Base {
Foo(bool b, int i);
}
class DerivedB : public Base {
Foo(bool b);
}
В C ++ 11 вы можете использовать override
спецификатор, который, я считаю, также поддерживается как расширение MSVC для кода C ++ 03.
Если вы используете G ++ или Clang, передача -Woverloaded-virtual
к компилятору это то, что вы после я думаю. Для вашего примера выше, g ++ сообщает:
so_virt.cc:2:16: warning: ‘virtual void Base::Foo(bool, int)’ was hidden [-Woverloaded-virtual]
virtual void Foo(bool b, int i);
^
so_virt.cc:10:8: warning: by ‘void DerivedB::Foo(bool)’ [-Woverloaded-virtual]
void Foo(bool b);
override
спецификатор может быть тем, что вы хотите. Если вы используете его в декларации Foo
в производных классах вы получите ошибку для DerivedB::Foo
так как он получил другую подпись.
class Base {
virtual Foo(bool b, int i);
}
class DerivedA : public Base {
Foo(bool b, int i) override; // would be fine
}
class DerivedB : public Base {
Foo(bool b) override; // gives an error
}
Выдает ошибку, если функция в производном классе получила другую сигнатуру от той, что в базовом классе, или если функция в базовом классе не объявлена virtual
,
Нет никакого способа заставить людей использовать спецификатор переопределения в производных классах, так что вы все равно должны помнить об его использовании. Но это может, по крайней мере, отловить ошибки при изменении сигнатуры функции. Для получения дополнительной информации о переопределении взгляда Вот.
class Base {
virtual Foo(bool b, int i) = 0;
}
class DerivedA : public Base {
Foo(bool b, int i);
}
class DerivedB : public Base {
Foo(bool b);
}
Обратите внимание, как я добавил =0
в virtual Foo(bool b, int i) = 0