TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.37K subscribers
Post #1014 4.09K
Доступ к приватным членам. Sutter hack
#опытным

Спасибо @d7d1cd за идею для поста)

В любой системе есть дырки, которые могут(и обязательно будут) эксплуатировать заинтересованные люди. Вот и в С++ так же. Сегодня мы раскроем, как можно стандартными относительно неинвазивными(не изменяя первоначальный код класса) инструментами изменять приватные поля класса.

Возьмем простой класс:

class X {
public:
X() : private_(1) {}

template <class T>
void f(const T &t) {}

int Value() { return private_; }

private:
int private_;
};


Чтобы трюк сработал, в классе должен быть шаблонный метод.

Теперь следите за руками.

Стандарт говорит, что вы самые хамские-хамы, если пытаетесь получить доступ к непубличным членам и будете за это жестко наказаны. Они должны быть использованы только внутри методов класса.

Дак, мы и не против. Давайте просто впишем новый метод класса, где изменим приватное поле, как нам нужно. И для этого даже не нужно менять код класса. И ключ ко всему - шаблонный метод.

Мы можем вне класса специлизировать шаблон метода для работы с конкретным типом. Специализация шаблона метода - это такой же метод с такими же правами, он может получать доступ к непубличным полям.

И тогда класс будет себя вести именно так, как мы ему скажем. А скажем мы ему пару ласковых:

struct Y {};

template <>
void X::f(const Y &) {
private_ = 2;
}

int main() {
X x;
std::cout << x.Value() << std::endl; // prints 1
x.f(Y());
std::cout << x.Value() << std::endl; // prints 2
}


В специализированном методе мы изменяем приватное поле и для наглядности выводим значение приватного поля в консоль. Можете сами убедиться, что это работает.

Этот трюк был описан Гербом Саттером, поэтому и называется Sutter hack.

Однако с его помощью нельзя менять поведение стандартных объектов:

The behavior of a C++ program is undefined if it declares

- an explicit specialization of any member function of a standard library class template, or
- an explicit specialization of any member function template of a standard library class or class template, or
- an explicit or partial specialization of any member class template of a standard library class or class template, or
- a deduction guide for any standard library class template.


потому что явные специализации методов из STL приводят к ub.

В общем, интересно, как на стыке двух концепций - ООП и шаблонов - появляются такие интересные спецэффекты)

Hack the life. Stay cool.

#cppcore #template #fun
  • 👍 30
  • 🔥 13
  • ❤‍🔥 6
  • 🤯 5
  • ❤ 4
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 →