TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #698 5.91K
Дефолтные параметры виртуальных методов
#опытным

Как и в обычных функциях и методах класса, в виртуальных методах тоже можно определять параметры по-умолчанию. Однако, они могут вести себя не совсем так, как вы этого ожидаете. Спасибо, @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
  • ❤ 28
  • 🔥 9
  • 😱 6
  • 👍 3
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →