Я работаю с C ++ только 2-3 месяца, и недавно я узнал об идентификаторе, окончательный, это идет после виртуальной функции. По сей день я считал, что упущение виртуальный остановит распространение виртуальности но я ошибся. Это неявно распространяется.
У меня вопрос такой. Зачем разрешать неявное распространение? Почему не может существовать виртуальный сделать функцию виртуальной и отсутствовать виртуальный сделать функцию не виртуальной? Это лучше в некоторых обстоятельствах? или это было в тот день, когда виртуальный был впервые представлен?
В соответствии с Ответ Клиффорда, там даже есть компилятор, который генерирует предупреждение при отсутствии виртуальный.
почему виртуальность методов неявно распространяется в с
Я ожидал, что ссылка выше ответит на мой вопрос, но это не так.
———— Дополнение ————-
Есть комментарии по поводу вопроса о полезности этой функции.
Я думаю окончательный Ключевое слово на виртуальной функции — это то, что девиртуализирует функцию. Функция больше не может быть переопределена, поэтому производный класс должен повторно объявить функцию независимо от того, имеет ли она то же имя или нет.
Если окончательный отличается от девиртуализации, Помоги мне понять это.
Если окончательный не отличается, то полезность девиртуализации самоочевидна из того факта, окончательный был представлен.
Я согласен, что принуждение явное виртуальный будет производить ошибки, но мне любопытно, если есть другие причины.
Ответ относительно Зачем определенная особенность существует (или не существует), как правило, довольно сложно, так как она становится вопросом угадывания и мнений. Тем не менее, простой ответ может быть принцип наименьшего удивления. Придумать схему, которая имеет смысл и работает надежно и предсказуемо было бы сложно.
Что бы вообще означало «девиртуализация» функции? Если во время выполнения вы вызываете «девиртуализированную» функцию для объекта, будет ли он вместо этого использовать статический тип указателя? Если статический тип имеет виртуальную функцию, а тип времени выполнения — нет, что происходит?
#include <iostream>
struct A { virtual void f() const { std::cout << "A"; } };
struct B : A { void f() const { std::cout << "B"; } };
struct C : B { virtual void f() const { std::cout << "C"; } };
struct D : C { void f() const { std::cout << "D"; } };
void f(const A& o) { o.f(); }
int main()
{
// "devirtualized" real C++
f(A{}); // "A" "A"f(B{}); // "A" or "B"? "B"f(C{}); // "C"? "C"f(D{}); // oh god "D"}
Существует также тот факт, что для подавляющего большинства проектов, виртуальная функция имеет оставаться виртуальным во всей иерархии. требующий virtual
на всех них появятся всевозможные ошибки, которые будет очень сложно диагностировать. C ++ обычно старается держаться подальше от функций, которые требуют дисциплины, чтобы получить права.
Других решений пока нет …