2012-10-31 12 views
9

निम्न कोड के बारे में प्रश्न किताब से कर रहे हैंसी ++ आभासी विरासत

#include <iostream> 
using namespace std; 
class X{}; 
class Y: public virtual X{}; 
class Z: public virtual X{}; 
class A: public Y, public Z{}; 

int main() 
{ 
    cout<<sizeof(X)<<" "<<sizeof(Y)<<" "<<sizeof(Z)<<" "<<sizeof(A)<<endl; 
    return 0; 
} 

अपने कंप्यूटर (विंडोज, VS2010) में "सी ++ ऑब्जेक्ट मॉडल के अंदर", उत्पादन होता है:

Here're मेरे सवालों

1, sizeof (एक्स) = 1

पुस्तक का कहना है जब एक्स प्रकार दो उदाहरण उत्पन्न करता है, तो xa और xb कहें। संकलन ए में एक बाइट डालें ताकि xa और xb के पास अलग पता हो। मैं कारणों को काफी समझ नहीं पा रहा हूं।

2, sizeof (वाई) = 4

आभासी विरासत उपयोग करके, हम एक अतिरिक्त आभासी सूचक होगा? मुझे लगता है कि यह बहुरूपता में वर्चुअल पॉइंटर से अलग हो सकता है। क्या कोई मुझे वाई के लिए मेमोरी लेआउट दे सकता है?

धन्यवाद!

+0

प्रश्न के प्रति एक प्रश्न कृपया पहले प्रश्न के लिए –

+0

देखें, http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an- ऑब्जेक्ट ऑफ द रिक्त-क्लास? rq = 1 –

+1

मुझे लगता है कि आपका मुख्य प्रश्न यह है कि वाई गैर-पॉलीमोर्फिक क्लास एक्स से प्राप्त करने के लिए आभासी विरासत का उपयोग करता है, और वाई स्वयं गैर-पॉलीमोर्फिक है, क्या वायरलल उत्तराधिकारी स्वयं ही कारण बन जाएगा वाई के पास एक वी-टेबल है, इस प्रकार इसका आकार 4 है .. – CashCow

उत्तर

6
  1. संकलक नया एक चार जब वर्ग रिक्त है, तो यह अलग वस्तु
  2. sizeof (वाई) = 4 उत्पन्न कर सकते हैं, क्योंकि यह आभासी है विरासत, निर्माण vptr तालिका उत्पन्न करेगा जो 32-बिट सिस्टम
  3. पर दृश्य बाइट्स उपयोग/d1reportAllClassLayout का उपयोग कर रहे हैं-> सी/सी ++/ऑब्जेक्ट लेआउट उत्पन्न करने के लिए कमांड कक्षा वाई ऑब्जेक्ट लेआउट दृश्य पर होगा स्टूडियो:
  4. पुस्तक 'इनसाइड सी ++ ऑब्जेक्ट मॉडल' स्टैनले B लिप्पमैन द्वारा इस बहुत अच्छी तरह से


     class Y size(4): 
      +--- 
      0  | {vbptr} 
      +--- 
      +--- (virtual base X) 
      +---
Y::[email protected]: 0 | 0 1 | 4 (Yd(Y+0)X)

vbi: class offset o.vbptr o.vbte fVtorDisp X 4 0 4 0
1

खाली कक्षा का आकार हमेशा लौटाता है 1. एक खाली कक्षा के लिए एक डमी बाइट है।

A से Z के लिए वाई अन्य के लिए एक आभासी तालिका में दो प्रविष्टियों, रखती है

तो sizeof दो संकेत यानी 8.

Y और Z पकड़ दोनों में एक्स के एक ही प्रविष्टि है उनके आभासी मेज, इसलिए आकार है 4.

+0

मुझे बी और सी नामक कक्षाएं नहीं दिखाई देती हैं – CashCow

1

एक समझाया एक वस्तु एक वाई वस्तु, एक जेड वस्तु (इसी क्रम में) में शामिल हैं और केवल जाएगा एक एक्स ऑब्जेक्ट (वाई और जेड में पॉइंटर्स द्वारा संदर्भित), क्योंकि वाई और जेड दोनों एक्स से वस्तुतः वारिस करते हैं, इस प्रकार इसका अर्थ यह है कि जब एकाधिक विरासत केवल एक एक्स ऑब्जेक्ट खेलने के लिए आता है तो बच्चे-कक्षाओं में तत्काल होगा। अभी भी दो ऑब्जेक्ट्स (एक वाई, एक जेड) है और इस प्रकार आकार = 8 है (क्योंकि दोनों के पास आकार = 4 है)। लेकिन वाई ऑब्जेक्ट में एक्स और जेड दोनों पॉइंटर्स एक ही पते पर इंगित करेंगे।

विरासत पेड़ की तरह दिखेगा:

X 
/\ 
Y Z 
\/
    A 
0

कारण कक्षाओं में कम से कम 1 बाइट हो -must- कहते हैं कि हम एक्स की एक सरणी हैयदि वे 0 बाइट्स थे तो & सरणी [1] के पास & सरणी [3] जैसा ही पता होगा, कोई भी उम्मीद नहीं करेगा, कोड तोड़ देगा, अगर आपको उस कोड को लिखने के लिए कोड लिखना पड़ेगा और आम तौर पर नहीं बनाया जाएगा कोई समझ

Y बस

static void* virtual_ptr1 //note this is in virtual table and cannot be edited 

आप स्थैतिक चर के रूप में है कि आप हाथ/कोड द्वारा संपादित नहीं कर सकते (या कम से कम नहीं होना चाहिए) (वर्गों और आभासी कार्यों के लिए आभासी संकेत) vtables के बारे में सोच सकते हैं होगा। इसके बारे में सोचें कि कंपाइलर आरक्षित स्थिर चर

+1

मुझे कारण आकार (एक्स) = 1 के लिए यह स्पष्टीकरण पसंद है – Junjie

संबंधित मुद्दे