Kann man auf private Mitgliederfunktionen zugreifen, indem man sie in layoutfähige Typen umwandelt?
Aus der Diskussion dieser FrageWie wird der Zugriff für private Variablen in C ++ unter der Haube implementiert? Ich habe eine Variante vorgeschlagen: Kann man, anstatt auf ein privates Datenmitglied zuzugreifen, private Mitgliederfunktionen aufrufen, indem man sie überträgt und sich auf Layout-Kompatibilität verlässt?
Ein bisschen Code (inspiriert von Herb Sutters Kolumne)Gebrauch und Missbrauch von Zugriffsrechten )
#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;
};
Hinweis: Dies funktioniert (zumindest auf Ideone)! Gibt es da irgendwie die neuenC ++ 11 Standard gibt eingarantiert oder zumindest eineImplementierung definiert Umgehung der Zugriffskontrolle durch Layout-Kompatibilität und Neuinterpretation von_cast / static_cast?
EDIT1: Ausgang einIdeone
EDIT2: In Sutters Kolumne nennt er zwei Gründe, warum der obige Code nicht garantiert funktioniert (obwohl er in der Praxis funktioniert)
a) Es wird nicht garantiert, dass die Objektlayouts von X und BaitAndSwitch identisch sind, obwohl dies in der Praxis wahrscheinlich immer der Fall sein wird.
b) Die Ergebnisse des reinterpret_cast sind undefiniert, obwohl die meisten Compiler Sie versuchen lassen, die resultierende Referenz in der vom Hacker beabsichtigten Weise zu verwenden.
Bietet der neue C ++ 11-Standard jetzt diese Garantie für Layout / Reinterpret_cast?