मुझे पता है कि एकाधिक विरासत के मेमोरी लेआउट को परिभाषित नहीं किया गया है, इसलिए मुझे इस पर भरोसा नहीं करना चाहिए। हालांकि, क्या मैं इसे एक विशेष मामले में भरोसा कर सकता हूं। यही है, एक वर्ग में केवल एक "असली" सुपर क्लास है। अन्य सभी "खाली वर्ग" हैं, यानी, कक्षाएं जिनमें न तो फ़ील्ड और न ही वर्चुअल विधियां हैं (यानी उनके पास केवल गैर-वर्चुअल विधियां हैं)। इस मामले में, इन अतिरिक्त वर्गों को कक्षा के स्मृति लेआउट में कुछ भी नहीं जोड़ना चाहिए। (अधिक संक्षेप में, सी ++ 11 शब्द में, कक्षा में मानक-लेआउट)सी ++ "एकाधिक कक्षाओं" के साथ एकाधिक विरासत मेमोरी लेआउट
क्या मैं अनुमान लगा सकता हूं कि सभी सुपरक्लासों का कोई ऑफ़सेट नहीं होगा? उदा .:
#include <iostream>
class X{
int a;
int b;
};
class I{};
class J{};
class Y : public I, public X, public J{};
int main(){
Y* y = new Y();
X* x = y;
I* i = y;
J* j = y;
std::cout << sizeof(Y) << std::endl
<< y << std::endl
<< x << std::endl
<< i << std::endl
<< j << std::endl;
}
यहाँ, Y
X
केवल वास्तविक आधार वर्ग होने के साथ वर्ग है। कार्यक्रम (जब ++ जी के साथ 4.6 लिनक्स पर संकलित) के उत्पादन में इस प्रकार है:
0x233f010
0x233f010
0x233f010
0x233f010
जैसा कि मैंने निष्कर्ष निकाला, कोई पोई नहीं है नटर समायोजन। लेकिन क्या यह कार्यान्वयन विशिष्ट है या क्या मैं इस पर भरोसा कर सकता हूं। यानी, अगर मुझे I
(और मुझे पता है कि केवल ये वर्ग मौजूद हैं) का ऑब्जेक्ट प्राप्त होता है, तो क्या मैं इसे पर डालने के लिए reinterpret_cast
का उपयोग कर सकता हूं?
मेरी आशा है कि मैं इस पर भरोसा कर सकता हूं क्योंकि कल्पना कहती है कि किसी ऑब्जेक्ट का आकार कम से कम बाइट होना चाहिए। इसलिए, संकलक एक और लेआउट नहीं चुन सकता है। यदि X
के सदस्यों के पीछे I
और J
लेआउट होगा, तो उनका आकार शून्य होगा (क्योंकि उनके पास कोई सदस्य नहीं है)। इसलिए, ऑफसेट के बिना सभी सुपर क्लास को संरेखित करना एकमात्र उचित विकल्प है।
क्या मैं सही हूं या मैं आग से खेल रहा हूं अगर मैं I
से X
पर reinterpret_cast का उपयोग करता हूं?
विरासत, एकल या एकाधिक, खाली अड्डों का स्मृति लेआउट या नहीं, परिभाषित नहीं किया गया है। –
मैं कहूंगा कि आप आग से खेल रहे हैं, क्योंकि आप एक बहुत ही अजीब निर्माण करने की कोशिश कर रहे हैं जो निश्चित रूप से भविष्य में इसे समझने वाले किसी को भी दर्द और दुख का कारण बन जाएगा, भले ही आप अपग्रेड करते समय ब्रेक न करें आपका कंपाइलर! – Rook
सौभाग्य से, आपके कथन अब C++ 11 में सही नहीं हैं, उत्तर देखें :) – gexicide