Предположим, у меня есть следующий код
class base
{
public:
virtual void MyVirtual() { std::cout << "This is base MyVirtual \n";}
void NonVirtual() { std::cout << "This is base NonVirtual \n";}
};
class derA : public base
{
public:
void MyVirtual() { std::cout << "This is derA MyVirtual \n";}
void NonVirtual() { std::cout << "This is derA NonVirtual \n";}
};
class derB : public derA
{
public:
void MyVirtual() { std::cout << "This is derB MyVirtual \n";}
void NonVirtual() { std::cout << "This is derB NonVirtual \n";}
};
int main()
{
derA *da = new derB;
da->MyVirtual(); // "This is derB MyVirtual \n"
da->NonVirtual();
std::cin.get();
return 0;
}
Теперь мой вопрос: почему MyVirtual Method ведет себя как виртуальный, если он не отмечен как виртуальный в классе derA
?
2 ответа
В C ++ унаследованные виртуальные функции остаются виртуальными в производном классе даже без ключевого слова virtual
. Считается хорошей практикой писать virtual
для каждой унаследованной функции.
Обновить
Как указано в комментариях к C ++ 11, считается хорошей практикой включать ключевое слово override
сразу после декларатора. Это выявляет общий класс ошибок и явно проясняет намерение в коде.
Согласно Стандарту § 10.3 Пункт № 2
Если виртуальная функция-член vf объявлена в классе Base и в классе Derived, производном прямо или косвенно от Base, функция-член vf с тем же именем, параметром-тип-списком, cv-квалификацией и refqualifier (или отсутствием то же самое), поскольку объявлен Base :: vf, то Derived :: vf также является виртуальным (независимо от того, объявлен ли он таким образом) и переопределяет Base :: vf.
Вот ваш ответ, прямо из стандартов. Таким образом, не имеет значения, использовали ли вы ключевое слово virtual
в производном классе или нет.
Похожие вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.
override
A a = new B;
, вы получаете доступ к методу MyVirtual B через a (это стандартный полиморфизм). И когда вы пишетеB b; b.MyVirtual()
, наследования нет, и вы все равно получаете поведение B.