2010-03-22 7 views
5

निम्नलिखित कोड पर विचार करें:क्या प्रारंभिक सूची में निजी फ़ंक्शंस कॉल के मामले में यह अनिर्धारित व्यवहार है?

struct Calc 
{ 
    Calc(const Arg1 & arg1, const Arg2 & arg2, /* */ const ArgN & argn) : 
     arg1(arg1), arg2(arg2), /* */ argn(argn), 
     coef1(get_coef1()), coef2(get_coef2()) 
    { 
    } 

    int Calc1(); 
    int Calc2(); 
    int Calc3(); 

private: 
    const Arg1 & arg1; 
    const Arg2 & arg2; 
    // ... 
    const ArgN & argn; 

    const int coef1; // I want to use const because 
    const int coef2; //  no modification is needed. 

    int get_coef1() const { 
    // calc coef1 using arg1, arg2, ..., argn; 
    // undefined behavior?  
    } 
    int get_coef2() const { 
    // calc coef2 using arg1, arg2, ..., argn and coef1; 
    // undefined behavior? 
    } 

}; 

struct Calc पूरी तरह से परिभाषित नहीं है जब मैं get_coef1 फोन और get_coef2 इस कोड को मान्य है? क्या मुझे यूबी मिल सकती है?

+0

यह काम करता है ... लेकिन आप स्वयं को परेशानी के लिए सेट अप करते हैं। क्या होता है जब रखरखाव आता है, कोफ के बाद 'argZ' जोड़ें, और फिर गणना में' argZ' का उपयोग करता है? आपके पास यूबी होगा ... –

उत्तर

8

12.6.2.8: सदस्य कार्य (आभासी सदस्य कार्यों सहित, 10.3) निर्माण के तहत किसी वस्तु के लिए बुलाया जा सकता है। इसी तरह, निर्माण के तहत एक वस्तु टाइपिड ऑपरेटर (5.2.8) या गतिशील_कास्ट (5.2.7) का संचालन हो सकती है। हालांकि, यदि इन परिचालनों को सीटीओ-प्रारंभिक (या सीटीओ-प्रारंभिक रूप से सीधे या अप्रत्यक्ष रूप से बुलाए गए फ़ंक्शन में) में किया जाता है, तो आधार कक्षाओं के लिए सभी ज्ञापन प्रारंभकर्ता पूर्ण हो चुके हैं, ऑपरेशन का परिणाम अनिर्धारित है।

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

+0

+1 क्योंकि ओपी वास्तव में क्या जानना चाहता था इसके बिंदु पर यह अधिक है। –

3

चूंकि आपकी गणना पर निर्भर होने वाले चर पहले से ही कॉल के समय शुरू हो चुके हैं, यह अपरिभाषित व्यवहार नहीं होना चाहिए। संबंधित जानकारी के लिए this प्रश्न देखें।

+3

और ध्यान रखें कि सदस्यों को उस क्रम में प्रारंभ किया जाता है जिसमें उनकी घोषणाएं दिखाई देती हैं, न कि क्रम में वे प्रारंभकर्ता सूची में दिखाई देते हैं। यहां यह वही है लेकिन जागरूक रहें कि 'कॉन्स्ट एआर कोफ 1' डालें, 'ऊपर' कॉन्स Arg1 & arg1; '(और अपनी आरंभकर्ता सूची को समान रखें) * * यूबी बनायेगा। –

+0

मेरा प्रश्न प्रारंभिकरण के आदेश के बारे में नहीं है। जिस क्रम में उनकी घोषणाएं दिखाई देती हैं वह ठीक है। मैं 'get_calc1' कार्यों के बारे में पूछता हूं। क्या यह 'पॉइंटर वैध है, उदाहरण के लिए? 'arg2' प्रारंभ किया गया है, हां, सच है। लेकिन क्या मैं 'get_calc1' में 'arg2' तक पहुंच प्राप्त कर सकता हूं? –

+1

सदस्य फ़ंक्शंस को कॉल करना बिल्कुल ठीक है जो केवल प्रारंभिक सदस्य विशेषताओं को संदर्भित करता है। –

0

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

struct Foo 
{ 
    int a, b; 
    int c; 
    Foo(): c(1), a(1), b(1) {} 
}; 

कि निर्माता में, चर आदेश में initialised कर रहे हैं क, ख, ग तो, सूची में क्रम में कुछ भी नहीं मतलब है। इसलिए यदि b और c पर कुछ गणना का उपयोग करके a का मूल्य प्रारंभ करना चाहते हैं तो आपको a की b और c के बाद किसी बिंदु पर a की घोषणा को स्थानांतरित करने की आवश्यकता होगी।

+0

Thnks। लेकिन मेरा सवाल प्रारंभिकरण के आदेश के बारे में नहीं है। आप देख सकते हैं कि आदेश ठीक था। –

+0

मैंने जवाब दिया कि पहले कुछ शब्दों में। यह अनिर्धारित नहीं है, बशर्ते आदेश सही है, जो आपके मामले में है, तो आप ठीक हैं। –