Если я объявляю базовый класс (или интерфейсный класс) и указываю значение по умолчанию для одного или нескольких его параметров, должны ли производные классы указывать те же значения по умолчанию, а если нет, то какие значения по умолчанию будут проявляться в производных классах?
Приложение: меня также интересует, как это можно обрабатывать в разных компиляторах, а также какие-либо сведения о «рекомендуемой» практике в этом сценарии.
Ответы:
Виртуалы могут иметь значения по умолчанию. Значения по умолчанию в базовом классе не наследуются производными классами.
Какой тип по умолчанию используется, т. Е. Базовый класс или производный класс, определяется статическим типом, используемым для вызова функции. Если вы вызываете объект базового класса, указатель или ссылку, используется значение по умолчанию, обозначенное в базовом классе. И наоборот, если вы вызываете через объект производного класса, указатель или ссылку, используются значения по умолчанию, обозначенные в производном классе. Под стандартной цитатой есть пример, демонстрирующий это.
Некоторые компиляторы могут делать что-то другое, но вот что говорят стандарты C ++ 03 и C ++ 11:
Вот пример программы, чтобы продемонстрировать, какие значения по умолчанию выбраны. Я использую
struct
s здесь, а неclass
es просто для краткости -class
иstruct
они практически одинаковы почти во всех отношениях, кроме видимости по умолчанию.Вывод этой программы (на MSVC10 и GCC 4.4):
источник
Это была тема одного из первых постов Герба Саттера в начале недели .
Первое, что он говорит по этому поводу, не делай этого.
Более подробно, да, вы можете указать различные параметры по умолчанию. Они не будут работать так же, как виртуальные функции. Виртуальная функция вызывается для динамического типа объекта, а значения параметров по умолчанию основаны на статическом типе.
Дано
вы должны получить A :: foo1 B :: foo2 B :: foo1
источник
Это плохая идея, потому что аргументы по умолчанию, которые вы получите, будут зависеть от статического типа объекта, тогда как
virtual
отправляемая функция будет зависеть от динамического типа.То есть, когда вы вызываете функцию с аргументами по умолчанию, аргументы по умолчанию подставляются во время компиляции, независимо от того, есть функция
virtual
или нет.@cppcoder предложил следующий пример в своем [закрытом] вопросе :
Который производит следующий вывод:
С помощью приведенного выше объяснения легко понять, почему. Во время компиляции компилятор заменяет аргументы по умолчанию из функций-членов статических типов указателей, делая
main
функцию эквивалентной следующему:источник
Как вы можете видеть из других ответов, это сложный вопрос. Вместо того, чтобы пытаться сделать это или понять, что он делает (если вы должны спросить сейчас, сопровождающий должен будет спросить или найти его через год).
Вместо этого создайте общедоступную не виртуальную функцию в базовом классе с параметрами по умолчанию. Затем он вызывает закрытую или защищенную виртуальную функцию, которая не имеет параметров по умолчанию и при необходимости переопределяется в дочерних классах. Тогда вам не нужно беспокоиться о том, как это будет работать, и код очень очевиден.
источник
Это тот, который вы, вероятно, сможете понять достаточно хорошо, протестировав (то есть, это достаточно основная часть языка, и большинство компиляторов почти наверняка понимают это правильно, и если вы не увидите различий между компиляторами, их вывод можно считать довольно авторитетным).
источник
Как подробно описали другие ответы, это плохая идея. Однако, поскольку никто не упоминает о простом и эффективном решении, вот оно: Преобразуйте ваши параметры в struct, и тогда у вас могут быть значения по умолчанию для членов структуры!
Так что вместо
сделай это,
источник