2012-06-24 27 views
26

ठीक है, प्रारंभिक सूची में अन्य सदस्य चर प्रारंभ करने के लिए सदस्य चर can be used (आरंभिक आदेश आदि के बारे में देखभाल के साथ)। सदस्य कार्यों के बारे में क्या? विशिष्ट होने के लिए, क्या यह स्निपेट सी ++ मानक के अनुसार कानूनी है?प्रारंभिक सूची में सदस्य चर को प्रारंभ करने के लिए सदस्य फ़ंक्शंस का उपयोग किया जा सकता है?

struct foo{ 
    foo(const size_t N) : N_(N), arr_(fill_arr(N)) { 
    //arr_ = fill_arr(N); // or should I fall back to this one? 
    } 

    std::vector<double> fill_arr(const size_t N){ 
    std::vector<double> arr(N); 
    // fill in the vector somehow 
    return arr; 
    } 

    size_t N_; 
    std::vector<double> arr_; 
    // other stuff 
}; 
+0

सवाल अच्छा है, लेकिन कोड नमूना कुछ हद तक कृत्रिम है। आपको 'fill_arr' को 'स्थिर' घोषित करने से क्या रोकता है और इसमें कोई संदेह नहीं है कि यह कानूनी है? –

+0

क्या यह थ्रेड-सुरक्षित होगा? मेरा मतलब है, 'fill_arr' के लिए एक वेक्टर स्थानीय है, अगर यह 'स्थिर' है, तो क्या मैं इसे एक प्रकार के म्यूटेक्स से सुरक्षित रखूंगा? –

+2

'std :: vector arr' में _automatic storage_ है, इसलिए फ़ंक्शन 'fill_arr' के प्रत्येक आमंत्रण के लिए इसका एक उदाहरण होगा। यह मूल है _C++ _... –

उत्तर

30

हां, प्रारंभिक सूची में सदस्य फ़ंक्शन का उपयोग मान्य है और मानक का अनुपालन करता है।

डेटा सदस्यों को उनकी घोषणा के क्रम में आरंभ किया गया है (और यही कारण है कि उन्हें अपनी घोषणा के क्रम में आरंभिक सूची में दिखना चाहिए - आपके द्वारा आपके द्वारा अनुसरण किए जाने वाले नियम)। N_ पहले आरंभ किया गया है और आप इस डेटा सदस्य को fill_arr पर पारित कर सकते थे। fill_arr को कन्स्ट्रक्टर से पहले बुलाया जाता है लेकिन चूंकि यह फ़ंक्शन अनियंत्रित डेटा सदस्यों तक नहीं पहुंचता है (यह डेटा सदस्यों तक नहीं पहुंचता है) इसकी कॉल सुरक्षित माना जाता है।

§ 12.6.2.13:: सदस्य कार्य (आभासी सदस्य कार्यों सहित 10.3) कहा जा सकता है

यहाँ सी ++ मानक के नवीनतम मसौदा (N3242 = 11-0012) से कुछ प्रासंगिक excepts हैं निर्माण के तहत एक वस्तु के लिए। (...) हालांकि, यदि इन परिचालनों को सीटीओआर-प्रारंभिक (या एक समारोह में सीटीओ-प्रारंभकर्ता से सीधे या परोक्ष रूप से कहा जाता है) में किया जाता है, तो सभी कक्षाओं के लिए मेम-प्रारंभकर्ताओं के पहले पूरा हो गया, ऑपरेशन का परिणाम अपरिभाषित है। उदाहरण:

class A { public: A(int); }; 

class B : public A { 
    int j; 
public: 
    int f(); 
    B() : A(f()), // undefined: calls member function 
       // but base A not yet initialized 
    j(f()) { } // well-defined: bases are all initialized 
}; 

class C { 
public: 
    C(int); 
}; 

class D : public B, C { 
    int i; 
public: 
    D() : C(f()), // undefined: calls member function 
       // but base C not yet initialized 
    i(f()) { } // well-defined: bases are all initialized 
}; 

§12.7.1: एक गैर तुच्छ निर्माता के साथ एक वस्तु, निर्माता से पहले करने के लिए वस्तु के किसी भी गैर स्थिर सदस्य या आधार वर्ग चर्चा करते हुए के लिए में निष्पादन के परिणामों शुरू होता है अपरिभाषित व्यवहार। उदाहरण

struct W { int j; }; 
struct X : public virtual W { }; 
struct Y { 
    int *p; 
    X x; 
    Y() : p(&x.j) { // undefined, x is not yet constructed 
    } 
}; 
3

जबकि प्रारंभ सूची में आरंभ वस्तुओं, वस्तु अभी तक पूरी तरह से निर्माण नहीं कर रहा है।
यदि वे फ़ंक्शन उस ऑब्जेक्ट के उस हिस्से तक पहुंचने का प्रयास करता है जो अभी तक नहीं बनाया गया है तो यह एक अनिर्धारित व्यवहार है और यह ठीक है।
this answer देखें।

+0

यह वास्तव में प्रश्न का मांस है: सदस्य कार्यों के निर्माण के लिए नियम क्या हैं? –

+0

@Zhenya इसे देखें :: http://stackoverflow.com/a/3899583/981787 – Eight

+0

यदि मैं गलत हूं तो मुझे सही करें: प्रश्न जो आप सदस्य कार्यों के बजाय सदस्य चर के साथ सौदा करने का जिक्र कर रहे हैं। क्या आप इंगित करते हैं कि सदस्य कार्य एक ही नियम का पालन करते हैं? एक के लिए, जीसीसी 4.4.3 शिकायत नहीं करता है अगर मैं 'arr_' ​​और' fill_arr() 'की घोषणाओं के आदेश को स्विच करता हूं, जबकि यह चेतावनी उत्सर्जित करता है अगर इन-सूची में ऑर्डर घोषणाओं के क्रम के समान नहीं है । –

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