2011-06-29 12 views
11
class D: A 
{ 
    B obj; 
    C obj2; 
} 

यहां निर्माण का आदेश की गारंटी है?प्रारंभिकरण के वर्ग घटक क्रम

मुझे पता है कि डी ए, बी और सी के बाद निर्माण किया जाएगा, लेकिन क्या मैं सच में जानना चाहते हैं कि क्या एक गारंटी बी या सी से पहले निर्माण किया जा रहा है है, या यहाँ तक कि क्या बी गारंटी है होना करने के लिए

D(): A(), B(), C() 
{} 

लेकिन वह initialiser सूची क्रम निर्धारित कैसे करता initialisation के: सी

मुझे पता है तुम एक स्पष्ट initialiser सूची हो सकता है पहले का निर्माण किया?

इसके अलावा, क्या कोई भी घटक डिफ़ॉल्ट डिज़ाइनर करता है या नहीं करता है?

+1

मुझ पर चिल्लाना बंद करो! –

उत्तर

10

सी ++ 03 मानक आईएसओ/आईईसी 14882: 2003 (ई) §12.6.2/5 [class.base से।init]:

प्रारंभ निम्न क्रम में आगे बढ़ना होगा:
- सबसे पहले, और केवल सबसे व्युत्पन्न वर्ग के निर्माता के लिए के रूप में नीचे वर्णित है, आभासी आधार वर्ग क्रम में वे गहराई पर प्रकट में प्रारंभ किया जाएगा - बेस क्लास के निर्देशित विश्वकोश ग्राफ के पहले बाएं से दाएं ट्रैवर्सल, जहां "बाएं से दाएं" व्युत्पन्न वर्ग आधार-विनिर्देश-सूची में बेस क्लास नामों की उपस्थिति का क्रम है।
- फिर, प्रत्यक्ष आधार कक्षाओं को घोषणा आदेश में प्रारंभ किया जाएगा क्योंकि वे बेस-विनिर्देशक सूची में दिखाई देते हैं (मेम-प्रारंभकर्ता के आदेश के बावजूद)।
- फिर, नॉनस्टैटिक डेटा सदस्यों को कक्षा परिभाषा में घोषित क्रम में शुरू किया जाएगा (फिर भी मेम-प्रारंभकर्ता के आदेश के बावजूद)।
- अंत में, कन्स्ट्रक्टर का शरीर निष्पादित किया जाता है।
[नोट: घोषणापत्र आदेश यह सुनिश्चित करने के लिए अनिवार्य है कि बेस और सदस्य सबोबजेक्ट प्रारंभिकरण के विपरीत क्रम में नष्ट हो जाएं। ]

तो इस मामले में, आप की गारंटी है कि प्रारंभ के आदेश पहले आधार वर्ग A, तो subobject B (यह वर्ग परिभाषा वर्ग के सदस्यों की सूची में पहले प्रकट होता है के बाद से) हो जाएगा, तो subobject C। प्रारंभकर्ता सूची का क्रम अप्रासंगिक है, जैसा कि किसी भी सदस्य के पास डिफ़ॉल्ट कन्स्ट्रक्टर नहीं है या नहीं, यदि किसी सदस्य के पास डिफॉल्ट कन्स्ट्रक्टर नहीं है और इसे प्रारंभिक सूची में स्पष्ट रूप से प्रारंभ नहीं किया गया है, तो उसके पास एक अनिर्दिष्ट मूल्य।

9

लेकिन क्या प्रारंभिक सूची प्रारंभिकरण के आदेश को निर्धारित करती है?

नहीं। प्रारंभिक सूची-सूची सदस्य डेटा और बेस सबोबजेक्ट (ओं) के प्रारंभिक क्रम का निर्धारण निर्धारित नहीं करता है। सदस्य अपने घोषणा के क्रम में प्रारंभ कर रहे हैं, और आधार subobjects निर्माण कर रहे हैं उनके उल्लेख के क्रम में - बाएं से दाएं:

struct A : B, C {} //B is constructed before C 

इसके अलावा, आधार subobjects सदस्य डेटा के प्रारंभ से पहले निर्माण कर रहे हैं। ऊपर struct में प्रारंभ की

struct A : B, C 
{ 
     D d; 
     E e; 
}; 

आदेश:

B  => C  => d => e 
subobject subobject  member member 

और वे उलटे क्रम में विलुप्त कर रहे हैं।

+0

स्पष्ट होने के लिए, यह घोषणा का आदेश है जो प्रारंभिकरण के आदेश को नियंत्रित करता है –

+0

ठीक है, आधार वर्ग बनाम सदस्य वस्तुओं के बारे में क्या, प्रारंभिक होने की गारंटी है? मुझे लगता है कि तकनीकी रूप से आधार वर्ग सदस्यों के सामने घोषित किए जाते हैं, तो क्या इसका मतलब हां है? :) – matt

+0

@matt: अब जवाब देखें। – Nawaz

1

शायद टूटा कोड के इस उदाहरण में मदद मिलेगी चित्रण करते हैं:

अगर मैं ऐसा तरह एक वर्ग को परिभाषित:

class Connection { 

    boost::asio::tcp::ip::socket _socket; 
    boost::asio::io_service _io_service; 

    Connection() : _io_service(), _socket(_io_service) 
    { 
    } 
}; 

यह सभी आधुनिक compilers में असफल हो जायेगी। चूंकि _socket को प्रथम श्रेणी के सदस्य के रूप में परिभाषित किया गया है, प्रारंभिक सूची पहले इसे आरंभ करने का प्रयास करेगी, इस तथ्य के बावजूद कि प्रारंभिक सूची संकलक को _io_service प्रारंभ करने के लिए कहती है। लेकिन चूंकि _io_service अभी तक शुरू नहीं हुआ है (सॉकेट कन्स्ट्रक्टर प्रारंभिक _io_service पर निर्भर करता है), _socket की शुरुआत सेगफॉल्ट का कारण बन जाएगा।

शायद कोई इस मानक को निर्धारित करने वाले मानक के उचित खंड को उद्धृत कर सकता है।

प्रश्न के दूसरे भाग के लिए, कक्षा वर्ग हमेशा कक्षा के सदस्यों के समक्ष शुरू किया जाएगा।

+0

"आधुनिक कंपाइलर पर" आपका क्या मतलब है? मैं कम से कम टीसी 3.0 के बाद से सी ++ के साथ काम कर रहा हूं और मुझे एक कंपाइलर याद नहीं है जिसे प्रारंभिक क्रम गलत मिला है। – sbi

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