Можно ли получить доступ к закрытым функциям-членам посредством приведения к типам, совместимым с макетом?
Из обсуждения этого вопросаКак осуществляется доступ к закрытым переменным в C ++? Я предложил вариант: вместо доступа к закрытому элементу данных можно ли вызывать закрытые функции-члены посредством приведения и полагаться на совместимость макета?
Некоторый код (вдохновленный колонкой Херба СаттераИспользование и злоупотребление правами доступа )
#include <iostream>
class X
{
public:
X() : private_(1) { /*...*/ }
private:
int Value() { return private_; }
int private_;
};
// Nasty attempt to simulate the object layout
// (cross your fingers and toes).
//
class BaitAndSwitch
// hopefully has the same data layout as X
{ // so we can pass him off as one
public:
int Value() { return private_; }
private:
int private_;
};
int f( X& x )
{
// evil laughter here
return (reinterpret_cast<BaitAndSwitch&>(x)).Value();
}
int main()
{
X x;
std::cout << f(x) << "\n"; // prints 0, not 1
return 0;
};
Примечание: это работает (по крайней мере, на Ideone)! Есть ли способ, новыйСтандарт C ++ 11 даетguaranteed или хотя быimplementation-defined способ обойти контроль доступа, полагаясь на совместимость макета и reinterpret_cast / static_cast?
EDIT1: вывод наIdeone
EDIT2В столбце Саттера он перечисляет две причины, по которым приведенный выше код не гарантированно работает (хотя он работает на практике).
a) The object layouts of X and BaitAndSwitch are not guaranteed to be the same, although in practice they probably always will be.
b) The results of the reinterpret_cast are undefined, although most compilers will let you try to use the resulting reference in the way the hacker intended.
Предоставляет ли новый стандарт C ++ 11 теперь эти гарантии layout / reinterpret_cast?