3.8Kпросмотров
40.9%от подписчиков
4 марта 2026 г.
Score: 4.2K
Доступ к приватным членам. Явная инстанциация и друзья
#опытным Оказывается способов легально залезть в непубличные кишки вашего класса довольно много, и сегодня обсудим еще один метод. Мы уже с вами говорили про дружественные функции и что им дозволено получать доступ к приватным членами класса. Но давайте посмотрим на следующий пример: template <typename T>
struct Foo { friend void bar() { cout << "Got it!" << endl; }
}; void bar();
template struct Foo<int>; bar(); У нас есть шаблонная структура и у нее есть дружественная функция. Пока шаблон не инстанцирован, компилятор не видит определения функции. Поэтому чтобы вызвать bar, нужно явно инстанцировать шаблон и объявить функцию во внешнем скоупе, чтобы компилятор мог найти ее по имени. Давайте проследим, что произошло. Функция bar - по сути свободная функция, которая может использовать все члены Foo. Но не только их. Она еще может использовать шаблонные параметры конкретной инстанциации. И вот тут мы возвращаемся к тому, что использование имени приватного поля абсолютно законно в контексте явной инстанциации(см. предыдущий пост). Давайте сделаем шаблонный параметр Foo указателем на поле и инстанцируем этот шаблон с указателем на приватное поле класса: class Private {
private: int data{};
}; template<int Private:: Member> // pointer to data member
struct Stealer { friend int& dataGetter(Private& iObj) { return iObj.Member; }
}; template struct Stealer<&Private::data>; // explicit instantiation
int& dataGetter(Private&); int main() { Private obj; dataGetter(obj) = 42;
} Вот и все, получаем ссылку на приватное поле и крутим его, как хотим. Можно поиграться с примером тут. И еще один из шаблоны сломали инкапсуляцию. Да что ж это такое! Спасибо, @SoulslikeEnjoyer, за материалы для поста) Exploit loopholes. Stay cool. #cppcore #template #fun