2008-10-02 15 views
13

मैंने आज एक सहयोगी के कुछ कोड को देखा जो प्रारंभिक कक्षा में प्रारंभिक वर्ग चर शुरू करता है। हालांकि, यह चेतावनी पैदा कर रहा था, वह कहता है कि वे किस क्रम में हैं। मेरा सवाल यह है कि चरम प्रारंभिकता करना बेहतर क्यों है, जहां वर्तमान में यह घुंघराले ब्रैकेट के भीतर है?सी ++ कक्षा प्रारंभिकरण जिसमें क्लास वेरिएबल प्रारंभिकता

DiagramScene::DiagramScene(int slideNo, QRectF screenRect, MainWindow* parent) 
    : QGraphicsScene(screenRect, parent), 
    myParent(parent), 
    slideUndoImageCurrentIndex(-1), 
    nextGroupID(0), 
    m_undoInProgress(false), 
    m_deleteItemOnNextUndo(0) 
    line(0), 
    path(0) 
{ 
    /* Setup default brush for background */ 
    scDetail->bgBrush.setStyle(Qt::SolidPattern); 
    scDetail->bgBrush.setColor(Qt::white); 
    setBackgroundBrush(scDetail->bgBrush); 

} 
+1

बस एक सामान्य शब्दावली टिप्पणी: यह सदस्य चर के बारे में है। सदस्य चर एक वस्तु से संबंधित हैं। क्लास चर C++ में मौजूद नहीं हैं, जबकि वे उदाहरण में करते हैं रूबी, और सी ++ स्थिर सदस्य चर के उद्देश्य को कम या ज्यादा सेवा प्रदान करते हैं। – xtofl

उत्तर

26
  • यह (सामान्य रूप में) और अधिक कुशल है। कक्षा के सभी सदस्यों को कन्स्ट्रक्टर में शुरू किया जाता है, भले ही आप उन्हें स्पष्ट रूप से प्रारंभ करें या नहीं। यदि आप प्रारंभकर्ता निर्दिष्ट नहीं करते हैं, तो सदस्य का डिफ़ॉल्ट कन्स्ट्रक्टर चलाया जाता है। यदि आप कन्स्ट्रक्टर बॉडी में कोई मान निर्दिष्ट करते हैं, तो असाइनमेंट ऑपरेटर को फिर से कॉल किया जाता है। यह स्केलर मानों पर लागू नहीं होता है, जैसा कि आपके उदाहरण में है, क्योंकि स्केलर मानों में कन्स्ट्रक्टर नहीं होते हैं।
  • आप प्रारंभिक सूची में गलती से मूल्य दो बार असाइन नहीं कर सकते हैं।
  • संकलक यह सुनिश्चित करने के लिए जांच कर सकता है कि जिस क्रम में आप प्रारंभिक लिखते हैं वह क्रम उस क्रम से मेल खाता है जिसमें सदस्यों को कक्षा में परिभाषित किया जाता है। सी ++ मानक के लिए आवश्यक है कि सदस्यों को घोषित क्रम में आरंभ किया गया हो, भले ही आप प्रारंभिक लिखने वाले आदेश के बावजूद। संकलक जांचने के बाद यह आदेश सुनिश्चित करता है कि प्रोग्रामर जानता है कि शुरुआती आदेश किस क्रम में चलाए जाएंगे (फिर से, यह गैर-पीओडी सदस्यों के लिए स्केलर्स की तुलना में अधिक महत्वपूर्ण है)।
  • संदर्भ प्रकार और const सदस्यों को आरंभकर्ता सूची में प्रारंभ किया जाना चाहिए, क्योंकि आप किसी संदर्भ या const सदस्य को असाइन नहीं कर सकते हैं।
2

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

इसके अलावा, कुछ प्रकार डिफ़ॉल्ट-निर्मित नहीं हो सकते हैं (उदाहरण के लिए संदर्भ) और प्रारंभिक सूची में बनाया जाना चाहिए।

+0

धन्यवाद, संदर्भों के बारे में जोड़ा गया नोट। +1 –

2

पर एकत्र बुद्धि पर एक नजर डालें तो आप स्थिरांक चर है, उनके मूल्य काम के माध्यम से सेट नहीं किया जा सकता है।

प्रारंभिक वस्तुएं ऑब्जेक्ट्स (अंतर्निर्मित या अंतर्निहित नहीं) के मूल्यों को आवंटित करते समय भी एक और अधिक कुशल होती हैं क्योंकि एक अस्थायी वस्तु के रूप में यह असाइनमेंट के लिए नहीं बनाया जाता है।

अधिक जानकारी के

4

यह प्रारंभ सूची में सदस्यों की प्रारंभ करने के लिए, क्योंकि सदस्यों तो केवल एक बार प्रारंभ कर रहे हैं बेहतर है के लिए C++ FAQ-Lite देखें। यदि सदस्य स्वयं कक्षाएं हैं तो यह प्रदर्शन (और यहां तक ​​कि व्यवहार) में एक बड़ा अंतर हो सकता है। यदि सदस्य सभी गैर-कॉन्स, गैर-संदर्भ मौलिक डेटा प्रकार हैं, तो अंतर आम तौर पर नगण्य होता है।

नोट: ऐसे समय होते हैं जहां प्रारंभिक डेटा प्रकारों के लिए प्रारंभिक सूचियों की आवश्यकता होती है - विशेष रूप से यदि प्रकार निरंतर या संदर्भ है। इन प्रकारों के लिए, डेटा केवल एक बार शुरू किया जा सकता है और इस प्रकार इसे कन्स्ट्रक्टर के शरीर में प्रारंभ नहीं किया जा सकता है। अधिक जानकारी के लिए this article देखें।

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

  • आप प्रारंभ सूचियों पसंद करने के लिए सीखना:

    यह मेरी सिफारिश यह है कि है।

  • आपका सहकर्मी सदस्यों के प्रारंभिक क्रम (और चेतावनियों से बचने के लिए) नियमों को समझता है।
3

ग्रेग हेगिल के excellent answer के अलावा - प्रारंभिक सूची में कॉन्स्ट चर को सेट किया जाना चाहिए।

+0

धन्यवाद, कॉन्स सदस्यों के बारे में जोड़ा गया नोट। +1 –

0

ग्रेग के उत्तर में एक और जोड़ा: सदस्यों को जो कि किसी भी डिफ़ॉल्ट कन्स्ट्रक्टर वाले प्रकार के हैं, प्रारंभिक सूची में प्रारंभ किए जाने चाहिए।

0

ग्रेग हेगवेल के उत्तर में कुछ उत्कृष्ट सलाह है, लेकिन यह स्पष्ट नहीं करता है कि संकलक चेतावनी क्यों उत्पन्न कर रहा है।

जब किसी कन्स्ट्रक्टर की प्रारंभकर्ता सूची को संकलक द्वारा संसाधित किया जाता है, तो आइटम को प्रारंभिक क्रम में घोषित किया जाता है ताकि उन्हें कक्षा घोषणा में घोषित किया जा सके, क्रम में वे प्रारंभकर्ता सूची में दिखाई देने वाले क्रम में नहीं।

कुछ कंपाइलर चेतावनी उत्पन्न करते हैं यदि प्रारंभकर्ता सूची में ऑर्डर घोषणा आदेश से अलग है (इसलिए जब आप सूची के क्रम में आइटम प्रारंभ नहीं होते हैं तो आपको आश्चर्य नहीं होगा)। आप अपनी कक्षा की घोषणा शामिल नहीं करते हैं, लेकिन यह आपके द्वारा देखे जा रहे चेतावनी का संभावित कारण है।

इस व्यवहार के लिए तर्क यह है कि कक्षा के सदस्यों को हमेशा एक ही क्रम में प्रारंभ किया जाना चाहिए: यहां तक ​​कि जब कक्षा में एक से अधिक कन्स्ट्रक्टर होते हैं (जो सदस्यों को प्रारंभिक सूचियों में अलग-अलग आदेश दे सकते हैं)।

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