#опытным
Как и в обычных функциях и методах класса, в виртуальных методах тоже можно определять параметры по-умолчанию. Однако, они могут вести себя не совсем так, как вы этого ожидаете. Спасибо, @d7d1cd, за идею для поста)
Правильный ответ из поста выше -
0 2 0 0 .#include <iostream>
struct base {
virtual void foo(int a = 0) { std::cout << a << " "; }
virtual ~base() {}
};
struct derived1 : base {};
struct derived2 : base {
void foo(int a = 2) { std::cout << a << " "; }
};
int main() {
derived1 d1{};
derived2 d2{};
base & bs1 = d1;
base & bs2 = d2;
d1.foo();
d2.foo();
bs1.foo();
bs2.foo();
}
Дело вот в чем. Если реализация виртуальных методов выбирается по динамическому типу, то выбор дефолтных параметров определяется статическим типом.
То есть, если мы вызываем метод у объекта наследника(или через ссылку, или указатель), то выбирается дефолтное значение метода наследника.
А если мы вызываем метод по указателю или ссылке на базовый класс, то дефолтное значение будет взято из объявления метода в базовом классе.
Из-за такого поведения в коммьюнити не принято переопределять дефолтные параметры виртуальных методов в наследниках, потому что это может сильно осложнить отладку.
Вообще говоря, если так хочется задать значение по-умолчанию, то возможно стоит рассмотреть перегрузку с последующим перенаправлением вызова в общую реализацию. Но это уже по ситуации нужно смотреть, чтобы не плодить много виртуальных методов.
Или можно использовать идиому публичного невиртуального интерфейса. Тогда ваш публичный метод будет устанавливать значения по умолчанию и их никто не сможет переопределить, потому что метод будет сам невиртуальный.
Слышится легкое: "Эх, я когда-нибудь смогу выучить плюсы?...".
Don't be confusing. Stay cool.
#cppcore