निर्माण C++ में एक काफी कठिन विषय है। सरल उत्तर है यह पर निर्भर करता है। चाहे फू प्रारंभ किया गया हो या नहीं, फू की परिभाषा पर निर्भर करता है। दूसरे प्रश्न के बारे में: बार को प्रारंभ करने के लिए कैसे करें: आरंभिक सूचियां उत्तर हैं।
आम सहमति यह है कि फू डिफ़ॉल्ट रूप से अंतर्निहित डिफ़ॉल्ट कन्स्ट्रक्टर (कंपाइलर जेनरेट) द्वारा प्रारंभ किया जाएगा, जिसे सही रखने की आवश्यकता नहीं है।
यदि फू के पास उपयोगकर्ता को डिफॉल्ट कन्स्ट्रक्टर परिभाषित नहीं किया गया है तो Foo को प्रारंभ नहीं किया जाएगा। अधिक सटीक होना: बार या फू एक उपयोगकर्ता परिभाषित डिफ़ॉल्ट निर्माता कमी के प्रत्येक सदस्य को बार के संकलक उत्पन्न डिफ़ॉल्ट निर्माता द्वारा अप्रारंभीकृत किया जाएगा:
class Foo {
int x;
public:
void dump() { std::cout << x << std::endl; }
void set() { x = 5; }
};
class Bar {
Foo x;
public:
void dump() { x.dump(); }
void set() { x.set(); }
};
class Bar2
{
Foo x;
public:
Bar2() : Foo() {}
void dump() { x.dump(); }
void set() { x.set(); }
};
template <typename T>
void test_internal() {
T x;
x.dump();
x.set();
x.dump();
}
template <typename T>
void test() {
test_internal<T>();
test_internal<T>();
}
int main()
{
test<Foo>(); // prints ??, 5, 5, 5, where ?? is a random number, possibly 0
test<Bar>(); // prints ??, 5, 5, 5
test<Bar2>(); // prints 0, 5, 0, 5
}
अब, अगर फू तो एक उपयोगकर्ता परिभाषित निर्माता था यह होगा इस बात पर ध्यान दिए बिना कि बार उपयोगकर्ता ने कन्स्ट्रक्टर को प्रारंभ किया है या नहीं। यदि बार में उपयोगकर्ता परिभाषित कन्स्ट्रक्टर है जो फू के स्पष्ट रूप से (संभावित रूप से परिभाषित) कन्स्ट्रक्टर को स्पष्ट रूप से कॉल करता है, तो वास्तव में फू को प्रारंभ किया जाएगा। यदि बार की प्रारंभिक सूची फू कन्स्ट्रक्टर को कॉल नहीं करती है तो यह उस मामले के बराबर होगी जहां बार में कोई उपयोगकर्ता परिभाषित कन्स्ट्रक्टर नहीं था।
परीक्षण कोड को कुछ समझाने की आवश्यकता हो सकती है। हम इस बात पर रूचि रखते हैं कि संकलक वास्तव में कन्स्ट्रक्टर को कॉल करने वाले उपयोगकर्ता कोड के बिना चर को प्रारंभ करता है या नहीं। हम परीक्षण करना चाहते हैं कि ऑब्जेक्ट प्रारंभ किया गया है या नहीं। अब अगर हम किसी फ़ंक्शन में ऑब्जेक्ट बनाते हैं तो यह एक मेमोरी स्थिति को हिट करने के लिए हो सकता है जो छूटा हुआ था और पहले से ही शून्य शामिल है। हम सफलता से भाग्य को अलग करना चाहते हैं, इसलिए हम एक फ़ंक्शन में एक चर परिभाषित करते हैं और फ़ंक्शन को दो बार कॉल करते हैं। पहले भाग में, यह मेमोरी सामग्री प्रिंट करेगा और एक बदलाव को मजबूर करेगा। फ़ंक्शन पर दूसरी कॉल में, जैसे स्टैक ट्रेस समान है, वैरिएबल बिल्कुल उसी स्मृति स्थिति में आयोजित किया जाएगा। यदि इसे प्रारंभ किया गया था, तो इसे 0 पर सेट किया जाएगा, अन्यथा यह वही मान पुराने वैरिएबल को उसी स्थिति में रखेगा।
प्रत्येक परीक्षण रन में, मुद्रित पहला मान प्रारंभिक मान (यदि यह वास्तव में प्रारंभ किया गया था) या उस स्मृति स्थिति में मान है, तो कुछ मामलों में 0 होना होता है। दूसरा मान केवल एक परीक्षण है टोकन मैन्युअल रूप से इसे बदलने के बाद स्मृति स्थिति पर मान का प्रतिनिधित्व करता है। तीसरा मान फ़ंक्शन के दूसरे भाग से आता है। यदि चर प्रारंभ किया जा रहा है तो यह 0 पर वापस आ जाएगा। यदि ऑब्जेक्ट प्रारंभ नहीं किया गया है, तो इसकी मेमोरी पुरानी सामग्री रखेगी।
मैं सी ++ से परिचित हूं और मुझे अभी भी इस हद तक कुछ संदेह हैं। इसके अलावा, ज्यादातर उत्तर स्पष्ट रूप से बताते हैं कि फू डिफॉल्ट कन्स्ट्रक्टर को बुलाया जाएगा और तथ्य यह है कि यह फू की परिभाषा पर निर्भर करता है। क्या यह एक उपयोगकर्ता प्रदान किया गया है या डिफ़ॉल्ट कन्स्ट्रक्टर निहित है? क्या इसमें कोई निजी सदस्य विशेषता है? सी ++ में प्रारंभ करना आसान नहीं है। –
काफी मजाकिया है कि @xtofl पोस्टर से 'मैं सी ++ से परिचित हूं' को हटाने का अनुरोध करता हूं ... शायद अधिकांश लोग सी ++ के साथ 'परिचित' नहीं होते हैं जब लगभग सभी उत्तर गलत होते हैं। वास्तव में प्रारंभिकरण कठिन है, कुछ लोगों ने उत्तर दिया है कि उनके सी ++ ज्ञान @ जेरेडपायर, @ डिर्ककली, @ डेविड थॉर्नली साबित हुए हैं और अभी भी असफल रहे हैं। –