2010-01-11 15 views
16

बूल "बार" डिफ़ॉल्ट रूप से सत्य है, लेकिन यह गलत होना चाहिए, इसे कन्स्ट्रक्टर में initiliazied नहीं किया जा सकता है। क्या इसे स्थिर बनाये बिना झूठ बोलने का कोई तरीका है?एक सी ++ बूल var डिफ़ॉल्ट रूप से क्यों सच है?

कोड का सरलीकृत संस्करण:

foo.h

class Foo{ 
public: 
    void Foo(); 
private: 
    bool bar; 
} 

foo.c

Foo::Foo() 
{ 
    if(bar) 
    { 
    doSomethink(); 
    } 
} 
+10

आप इसे निर्माता में क्यों शुरू नहीं कर सकते? – Kena

+0

क्योंकि निर्माता को एक से अधिक बार बुलाया जा सकता है, मैं उस दिनचर्या को नहीं बदल सकता क्योंकि इसमें सॉफ़्टवेयर की बड़ी शांति नहीं होगी :( – Christoferw

+27

कन्स्ट्रक्टर को कभी भी एक से अधिक बार कैसे बुलाया जाएगा? – jalf

उत्तर

63

वास्तव में, डिफ़ॉल्ट रूप से यह कम से आरंभ नहीं किया है सब। आपके द्वारा देखी जाने वाली मान स्मृति में कुछ कचरा मान है जो आवंटन के लिए उपयोग की गई हैं।

आप एक डिफ़ॉल्ट मान सेट करना चाहते हैं, तो आप निर्माता में यह कहने की आवश्यकता होगी:

class Foo{ 
public: 
    Foo() : bar() {} // default bool value == false 
    // OR to be clear: 
    Foo() : bar(false) {} 

    void foo(); 
private: 
    bool bar; 
} 

अद्यतन सी ++ 11:

आप एक सी का उपयोग कर सकते हैं ++ 11 संकलक, अब आप के बजाय का निर्माण डिफ़ॉल्ट कर सकते हैं (ज्यादातर समय):

class Foo{ 
public: 
    // The constructor will be generated automatically, except if you need to write it yourself. 
    void foo(); 
private: 
    bool bar = false; // Always false by default at construction, except if you change it manually in a constructor's initializer list. 
} 
+8

और इसलिए आपके पास 'if (bar) 'सत्य होने का लगभग 100% मौका है। –

+2

कुछ कंपाइलर डीबग मेमोरी में मेमोरी को एक विशिष्ट पैटर्न में प्रारंभ करेंगे। यदि उन कंपाइलरों में से किसी एक का उपयोग करते हैं, तो डिबग बिल्ड में बार के 100% मौके होने का मौका होगा। –

+1

आईआईआरसी डार्विन डिफ़ॉल्ट रूप से स्मृति को शून्य से शुरू करता है, ताकि आप प्लेटफॉर्म पर असंगत व्यवहार के साथ समाप्त हो सकें। –

1

C/C++ बिल्कुल आप के लिए चर को प्रारंभ नहीं है। स्मृति स्थान जो अब बार द्वारा उपयोग में है, उसमें एक मूल्य था जिसे "सत्य" के रूप में व्याख्या किया गया है। यह हमेशा मामला नहीं होगा। आपको इसे अपने कन्स्ट्रक्टर में प्रारंभ करना होगा।

+0

यह निर्भर करता है। पीओडी सदस्य चर प्रारंभ नहीं किए जाते हैं, लेकिन गैर-पीओडी सदस्यों को डिफ़ॉल्ट रूप से निर्मित किया जाता है। और, ज़ाहिर है, वैश्विक/स्थैतिक चर प्रारंभ कर रहे हैं। – jamesdlin

1

इस कार्यक्रम में व्यवहार को अपरिभाषित किया गया है। आंतरिक प्रकारों में रचनाकार नहीं होते हैं। आप bool bar = bool(); कर सकते हैं लेकिन आपके foo क्लास में वास्तविक मान को परिभाषित करना बेहतर है।

0

इस प्रयास करें:

class Foo 
{ 
    public: 
    void Foo(); 
    private: 
    bool bar; 
} 

Foo::Foo() : bar(false) 
{ 
    if(bar) 
    { 
    doSomething(); 
    } 
} 
+0

foo() foo() नहीं है ... – Klaim

+0

ओह, @Klaim ने मुझे एक उदाहरण प्रदान करने के लिए हराया। – Bill

+0

foo() एक टाइपो है, foo() foo होना चाहिए() – Christoferw

-1

आप किसी भी चर को प्रारंभ कर सकते हैं जब आप इसे घोषणा करते हैं।

bool bar = 0; 
+0

मैं वही करता हूं, लेकिन मुझे एक C2864 त्रुटि मिलती है: केवल स्थिर कॉन्स अभिन्न डेटा सदस्यों को कक्षा – Christoferw

+1

के भीतर प्रारंभ किया जा सकता है यह स्थानीय चर के लिए सच है, लेकिन कक्षा के सदस्य नहीं। – Bill

+2

लेकिन सी ++ 0x से पहले नहीं ... – Debilski

4

कामे का जवाब स्पॉट पर है। अपनी समस्या को हल करने के लिए आप constructor initialization list का उपयोग कर सकते हैं। मैं दृढ़ता से सुझाव देता हूं कि आप उस पृष्ठ को पढ़ लें क्योंकि यह भविष्य में आपके कुछ समान प्रश्नों को साफ़ कर सकता है।

0

चूंकि आप ctor में बार के मान का उपयोग कर रहे हैं, मुझे लगता है कि आप ऑब्जेक्ट बनने से पहले इसे सेट करने का प्रयास कर रहे हैं? मुझे लगता है कि आप इसे एक आवृत्ति चर के बजाय एक स्थिर वर्ग चर बनाने के लिए मतलब है।

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