इस प्रश्न की चर्चा से How is access for private variables implemented in C++ under the hood? मैंने एक भिन्नता उत्पन्न की: एक निजी डेटा सदस्य तक पहुंचने के बजाय, क्या कोई लेआउट-संगतता पर कास्टिंग और भरोसा करके निजी सदस्य कार्यों को कॉल कर सकता है?क्या कोई लेआउट-संगत प्रकारों को कास्टिंग के माध्यम से निजी सदस्य कार्यों तक पहुंच सकता है?
कुछ कोड
#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;
};
नोट (हर्ब सुतर की स्तंभ Uses and Abuses of Access Rights से प्रेरित): इस काम करता है (कम से कम Ideone पर)! क्या कोई नया तरीका है C++11 Standardगारंटी या कम से कम कार्यान्वयन-परिभाषित लेआउट-संगतता और reinterpret_cast/static_cast पर भरोसा करके अभिगम नियंत्रण को रोकने के लिए तरीका देता है?
EDIT1: सुतर की स्तंभ में उन्होंने दो कारण हैं जिनकी वजह से ऊपर कोड काम करने के लिए गारंटी नहीं है सूचीबद्ध करता है (हालांकि यह व्यवहार में काम करता है)
एक): Ideone
EDIT2 पर उत्पादन एक्स और बैट एंड स्विच के ऑब्जेक्ट लेआउट को होने की गारंटी नहीं है, हालांकि व्यवहार में वे शायद हमेशा होंगे।
ख) reinterpret_cast के परिणामों अपरिभाषित कर रहे हैं, हालांकि ज्यादातर compilers दूँगी आप जिस तरह से हैकर का इरादा है, जिसके परिणामस्वरूप संदर्भ का उपयोग करने का प्रयास करें।
क्या नया सी ++ 11 मानक अब इन लेआउट/reinterpret_cast गारंटी प्रदान करता है?
आप 'reinterpret_cast'' के साथ जो कुछ भी चाहते हैं उसे बाधित कर सकते हैं; क्या आप पूछ रहे हैं कि एक अच्छी तरह से परिभाषित तरीके से ऐसा करना संभव है? –
@ ओली चार्ल्सवर्थ हां, गारंटी सबसे अच्छी होगी, कार्यान्वयन परिभाषित दूसरा सर्वश्रेष्ठ और यूबी इतना अच्छा नहीं है। – TemplateRex
कोई रास्ता नहीं। असेंबली लेवल क्लास विधि पर छुपा "यह" पैरामीटर के साथ सिर्फ वैश्विक कार्य है, यह क्लास इंस्टेंस से संबंधित नहीं है और इसे लेआउट ट्रिक्स के माध्यम से एक्सेस नहीं किया जा सकता है। –