TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #537 4.78K
​​Почему приватные методы находятся в описании класса?
#опытным

Публичные, защищенные методы - понятно, они нужны либо для пользователей класса, либо для наследников. Поля - понятно, они влияют на размер объекта, а клиенты должны уметь правильно аллоцировать нужное количество памяти под объект. Ну а приватные-то методы зачем раскрывать?

Приватные методы - это вообще-то детали реализации. Если я в своем фреймворке по-приколу назову какой-нибудь приватный метод KillTheNigga, то другим людям уже нельзя будет пользоваться этим фреймворком. Закенселлят еще меня. Хотя какая блин разница, какие у меня там приватные методы? Они типа и названы private, чтобы показать, что они МОИ ЛИЧНЫЕ(никому не отдам). А их оказывается нужно еще и показывать всем. Что-то не сходится.

Ну во-первых. Представим, что этого ограничения нет. Тогда все приватные методы объявлялись и определялись бы в файле реализации, который никто не видит. Но если я могу в файле реализации определить приватный метод, то кто угодно может это сделать. Это будет давать рандомным людям прямой доступ к закрытым полям класса. Если мы завершили определение класса, то у нас нет способов как-то пометить именно наши файлы, как "благословленные владельцем". Есть всего лишь юниты трансляции и они равнозначны. Получается, что единственный способ сказать, что вот этот набор методов официально одобрен создателем - это объявить его в описании класса.

На самом деле, в С++ мы имеем прямой доступ к памяти, в значит, мы легко можем поменять байтики для приватных полей и все. Или даже создать тип, с таким же описанием, только с дополнительным методом. Кастануть недоступный тип к своему и вуаля, вы можете как хотите вертеть объектом во всех удобных вам позах. Но это уже хаки, мы такого не одобряем. Не используя манипуляции с памятью, мы не сможем добавлять рандомную функциональность в рандомный класс.

А во-вторых, оказывается в С++ приватные методы участвуют в разрешении перегрузок(внезапно). В целом, так оно и должно быть. Никто не мешает вам определить публичный метод и перегрузить его приватным методом. Проблема(или фича) в том, что этап разрешения перегрузок стоит перед проверкой модификатора доступа. То есть даже если метод приватный и его никто не должен увидеть, он все равно участвует в разрешении перегрузок наряду со всеми остальными методами. Поэтому каждый клиент должен видеть полный набор приватных методов. Об этом мы уже говорили в контексте pimpl идиомы.

В чем прикол такого дизайн решения?

Давайте представим, что такого правила нет. И вот у нас есть две перегрузки, одна приватная для double, другая публичная для int. И перегрузка с double всегда отбрасывалась бы только лишь по причине того, что она приватная. Тогда мы легко можем вызвать публичную функцию с дробным числом 1.5 и нам ничего не будет. Оно просто неявно приведется к int и все на этом.

А теперь посмотрим, что будет, если мы поменяем модификатор приватной перегрузки на публичный? Ничего не упадет, НО! наш вызов метода с аргументом 1.5 теперь пойдет в другую функцию! То есть изменится поведение объекта. Комитет хотел избежать таких ситуаций, поэтому ввели такое вот ограничение. Наверное, причина не одна. Но это весомый аргумент.

Однако, такой протокол поведения влечет за собой различные сайд-эффекты. Я могу удалить(=delete) приватную перегрузку публичного метода, например какую мы обсуждали выше. И вызвать публичный метод опять с дробным числом. Но компилятор на меня наругается, потому что я попытался вызвать удаленную перегрузку метода. Хотя она вообще-то объявлена, как приватная! А то, что я ее удалил - это детали реализации. Получается раскрытие деталей реализации.

Stay aware. Stay cool.
#design #howitworks #cppcore #hardcore
  • 👍 21
  • 🔥 7
  • ❤ 4
  • ❤‍🔥 2
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
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 →