2010-11-12 11 views
25

मेरी आंत महसूस यह नहीं है। मैं निम्नलिखित स्थिति में हूँ:क्या कन्स्ट्रक्टर प्रारंभकर्ता सूची में कोई फ़ंक्शन कॉल करना ठीक है?

class PluginLoader 
{ 
    public: 
     Builder* const p_Builder; 
     Logger* const p_Logger; 

     //Others 
}; 

PluginLoader::PluginLoader(Builder* const pBuilder) 
    :p_Builder(pBuilder), p_Logger(pBuilder->GetLogger()) 
{ 
    //Stuff 
} 

या मैं निर्माता बदल सकते हैं और जहां PluginLoader निर्माण किया है से एक Logger* const पारित करना चाहिए?

उत्तर

27

यह बिल्कुल ठीक और सामान्य है। p_Builder इससे पहले शुरू किया गया था।

+0

जी। मैं एक 'गेट' होना चाहिए। :) – nakiya

+11

यह और भी इतना है, क्योंकि वह 'pbuilder-> GetLogger() 'को कॉल कर रहा है, नहीं' p_Builder-> GetLogger()'। दोनों कानूनी हैं, लेकिन दूसरा कक्षा परिभाषा में पुनरावर्तित आवृत्ति चर के प्रति संवेदनशील है। – Eclipse

+0

@ ग्रहण: ओह, मैंने यह भी नहीं देखा था। @nakiya: क्या आप सदस्य या पैरामीटर का उपयोग करना चाहते थे? या तो सुरक्षित है, जैसा है। – GManNickG

0

पूरी तरह से अच्छा अभ्यास। एक init समारोह में उन्हें समूह के बजाय कार्यों अपने निर्माता में बुलाया होने के

, केवल लचीलापन प्रयोजनों के लिए:

मैं इस सुझाव है (लेकिन एक विशुद्ध रूप से व्यक्तिगत स्तर पर अपनी) आप बाद में बनाने के लिए करता है, तो अन्य रचनाकार

+3

यदि आप जो सुझाव दे रहे हैं वह एक * निजी * 'init' फ़ंक्शन है जिसे आप कन्स्ट्रक्टर से कॉल करते हैं, तो मुझे इसकी परवाह नहीं है लेकिन मुझे लगता है कि यह ठीक है। यदि आप जो सुझाव दे रहे हैं वह एक * सार्वजनिक * 'init' फ़ंक्शन है जिसे कक्षा के उपयोगकर्ताओं द्वारा बुलाया जाना है, जो त्रुटियों और असंगतताओं के लिए प्रवण है (ऑब्जेक्ट बनाने के बाद यह अभी तक अमान्य स्थिति में होगा और उपयोगकर्ता भूल सकता है 'init' को कॉल करने के लिए या निर्माण और प्रारंभिकरण के बीच वस्तु का उपयोग करने का प्रयास करें ...) –

+0

आप एक डमी सदस्य का उपयोग कर सकते हैं, और init विधि एक प्रकार वापस कर सकते हैं।उदाहरण के लिए 'क्लास आईडीजेनरेटर { सार्वजनिक: आईडीजेनरेटर(); बूल रीसेट(); std :: uint32_t उत्पन्न(); निजी: बूल एमआरसेट; T_ID_set mIds; std :: uint32_t mId; }; IDGenerator :: IDGenerator() : mReset (रीसेट()) { } bool IDGenerator :: रीसेट() { mIds.clear(); एमआईडी = 0; सच वापसी; } ' – dgsomerton

19

आपके पास क्या ठीक है। हालांकि, मैं तो बस आप इस नहीं करने के लिए सावधान रहने की चेतावनी देने के लिए करना चाहते हैं:

class PluginLoader 
{ 
    public: 
     Logger* const p_Logger; // p_Logger is listed first before p_Builder 
     Builder* const p_Builder; 

     //Others 
}; 

PluginLoader::PluginLoader(Builder* const pBuilder) 
    :p_Builder(pBuilder), 
    p_Logger(p_Builder->GetLogger()) // Though listed 2nd, it is called first. 
             // This wouldn't be a problem if pBuilder 
             // was used instead of p_Builder 
{ 
    //Stuff 
} 

ध्यान दें कि मैं अपने कोड में 2 बदलाव किए (GMAN इस उल्लेख, मैं सिर्फ यह पूरी तरह से स्पष्ट करना चाहता था)। सबसे पहले, कक्षा परिभाषा में, मैंने p_BLilder से पहले p_Logger घोषित किया। दूसरा, मैंने पैरामीटर के बजाय, p_Logger को प्रारंभ करने के लिए सदस्य p_Builder का उपयोग किया।

या तो इनमें से कोई भी परिवर्तन ठीक होगा, लेकिन साथ में वे एक बग पेश करते हैं, क्योंकि p_Logger पहले प्रारंभ होता है, और आप इसे प्रारंभ करने के लिए अनियमित पीबीयूल्डर का उपयोग करते हैं।

बस हमेशा याद रखें कि सदस्यों को कक्षा परिभाषा में दिखाई देने के क्रम में प्रारंभ किया जाता है। और जिस क्रम में आप उन्हें अपनी प्रारंभिक सूची में डालते हैं वह अप्रासंगिक है।

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