क्या डिफॉल्ट कंस्ट्रक्टर को अनुपयोगी बनाना ठीक है?


14

विशेष रूप से डिफ़ॉल्ट कंस्ट्रक्टर के बारे में पूछ रहा है

यह देखते हुए कि कंस्ट्रक्टर किसी ऑब्जेक्ट के लिए सभी डेटा को इनिशियलाइज़ करता है, अगर मैं एक ऐसी क्लास बनाऊं जिसे बिना उचित इनिशियलाइज़ेशन के इस्तेमाल नहीं किया जा सके, तो क्या यह ऐसा नहीं है कि डिफॉल्ट कंस्ट्रक्टर बेकार है? विचार करें:

// A class for handling lines in a CSV file
class CSV_Entry {
private:
    unsigned num_entries;
    std::string string_version;
    std::vector<std::string> vector_version;
    ...etc
public:
    CSV_Entry();
    CSV_Entry(const std::string& src_line);

    // returns a vector copy of the original entry
    std::vector<std::string> get_vector_snapshot();
}

int main( void ) {
    ...etc

    CSV_Entry example = CSV_Entry();
    std::vector<std::string> current_entry = example.get_vector_snapshot();

    ...etc
}

वह चर current_entryअनिवार्य रूप से बेकार नहीं है? यदि कोई बाद में इसे संसाधित करने की कोशिश करता है, तो उन्हें संभवतः त्रुटियां मिलेंगी; फिर वे ऐसी त्रुटियों को संभालने के लिए कोड बनाएंगे ...

इस तरह के अतिरिक्त, अनावश्यक कोड को कम करने के लिए: डिफ़ॉल्ट निर्माता को अनुपयोगी क्यों न बनाया जाए? इस तरह,

...etc

CSV_Entry() {
    throw Verbose_Exception( "CSV_Entry: do not use the default constructor" );
}

...etc

पुनश्च: एक साइड नोट पर, यदि यह केवल डिफ़ॉल्ट कंस्ट्रक्टर को अनुपयोगी बनाने के लिए ठीक है, तो क्या उस फेंक को हेडर में रखना ठीक है, क्योंकि किसी भी अन्य कार्यान्वयन विवरण का कोई भी खुलासा नहीं होता है?

जवाबों:


34

हां, यह ठीक है (वास्तव में, यह अच्छा है ) डिफ़ॉल्ट कंस्ट्रक्टर को अनुपयोगी बनाने के लिए यदि किसी तर्क के बिना ऑब्जेक्ट को इनिशियलाइज़ करने का कोई समझदार तरीका नहीं है। लेकिन एक अपवाद को फेंककर इसे "अक्षम" न करें। इसके बजाय इसे निजी बनाएं। आदर्श रूप से आपके इंटरफ़ेस में ऐसी कोई विधियाँ या निर्माता नहीं होंगे, जिन्हें लोग "कॉल" करने वाले नहीं हैं।


1
तो, इसे निजी बनाने से, डिफ़ॉल्ट निर्माणकर्ता का उपयोग करने का प्रयास करने वाले उपयोगकर्ता को संकलन समय पर त्रुटि मिल जाएगी?
user2738698

@ user2738698 सही
डोभाल

8
यदि आप C ++ 11 का उपयोग कर सकते हैं, तो स्पष्ट रूप से हटाए गए के रूप में चिह्नित करें CSV_Entry() = delete;:।
बस्तमौर

13
वास्तव में, क्या यह इससे भी आसान नहीं है? यदि कोई गैर-डिफ़ॉल्ट निर्माता परिभाषित किया गया है, तो कंपाइलर डिफ़ॉल्ट रूप से डिफ़ॉल्ट निर्माता नहीं बनाएगा। इस वर्ग में एक नॉन-डिफॉल्ट कंस्ट्रक्टर परिभाषित है (जो मैं explicitसुझाऊंगा, बीटीडब्ल्यू)। इसलिए यदि आप इसे परिभाषित नहीं करते हैं, तो यह मौजूद नहीं होगा।
फ्रेड लार्सन

7
@FredLarson स्पष्ट रूप से इसे हटाने से इसे हटाने का इरादा व्यक्त होता है, इसलिए कोई यह नहीं सोचता कि यह एक गलती थी।
डार्कहॉग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.