2016-04-16 2 views
0

Я действительно не вижу смысла в переопределении не виртуальных методов, так как он создает целый ряд потенциальных ошибок, где иногда вызывается исходный базовый и иногда дочерний метод.Полезно ли всегда отмечать не виртуальные методы с помощью final?

Следуя этой логике, метод всегда приходит к простому правилу: Можно ли переопределить этот метод? Если да - отметьте его virtual, если нет - отметьте его final.

Для меня все звучит хорошо, но мне интересно, не хватает ли я чего-то важного и почему никто не следует этому простому правилу?

+4

A) вы не можете переопределить не виртуальные функции-члены. B) пытались ли вы пометить не виртуальную функцию-член как 'final'? – juanchopanza

+2

Вы не можете переопределять не виртуальные методы, а только скрывать их, и вы не можете использовать 'final' для не виртуальных методов. – milleniumbug

+1

Clang дает ошибку об этой ошибке: только функции виртуального участника могут быть помечены как «final», поэтому я бы пошел с «нет». – JVApen

ответ

1

Программа, которая содержит не виртуальную функцию и которая имеет любую не виртуальную функцию как final и следует стандарту C++, гарантированно будет полностью исключена.

Так что есть.

Ещё: советую против этого.

Этого также не существует. Ключевое слово position final может применяться только к функциям virtual. Первый абзац известен как шутка с произвольным удовлетворением: каждый пример несуществующей вещи имеет каждое свойство, потому что примеров нет.

Создание функции без переопределения virtual final будет путать людей, читающих ее. Это помешало бы типу-потомку объявить метод с идентичной сигнатурой: но это не помешало бы немного другой подписи, поэтому это в основном бессмысленно.

1

Вы абсолютно правы, каждая функция-член, которую вы пишете, должна быть явно запрограммирована для переопределения или быть инвариантной. Однако виртуальность - это то, что вы должны добавить на самом верху иерархии; вы не можете добавить его посередине. Тем не менее, вы можете «отнять» виртуальность от этого класса вниз, пометив виртуальную функцию-член final.

С final можно применять только к функциям виртуальных членов, мы не будем рассматривать не виртуальные функции-члены в обсуждении ниже.

Общепринятой практикой является создание класса для непосредственного использования или для наследования, но не для обоих, т. Е. Когда вы не создаете экземпляры классов в середине иерархии наследования и не наследуете от «листовых» классов иерархии , Эта практика была популяризирована в книге More Effective C++, пункт 33. Если вы следуете этой практике, вы должны пометить final все виртуальные функции классов листьев, чтобы компилятор помог вам найти все нарушения правила.

+0

'struct base {int x() {return 1; }}; struct mid: base {virtual int x() {return 2; }}; struct bottom: mid {virtual int x() {return 3; }}; 'не является допустимой программой? (Это плохая программа, но не должна быть не может) – Yakk

Смежные вопросы