この質問の議論から、フードの下でC++に実装されているプライベート変数へのアクセスはどのようになっていますか? 私はバリエーションを提示しました: プライベート データ メンバーにアクセスする代わりに、キャストとレイアウト互換性に依存してプライベート メンバー関数を呼び出すことができますか?
いくつかのコード (Herb Sutter のコラムUses and Abuses of Access Rights に触発されたもの)
#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 標準が、レイアウトの互換性と reinterpret_cast / static_cast に依存することによって、アクセス制御を回避する保証された、または少なくとも実装定義の方法を提供する方法はありますか?
EDIT1 : Ideoneでの出力
EDIT2 : Sutter のコラムで、彼は上記のコードが動作することが保証されていない理由を 2 つ挙げています (実際には動作しますが)。
a) X と BaitAndSwitch のオブジェクト レイアウトが同じであるとは限りませんが、実際には常に同じである可能性があります。
b) reinterpret_cast の結果は未定義ですが、ほとんどのコンパイラでは、ハッカーが意図した方法で結果の参照を使用しようとすることができます。
新しい C++11 標準では、これらのレイアウト / reinterpret_cast の保証が提供されるようになりましたか?