c++ कंस्ट्रक्टर में कॉन्स्टेबल सदस्यों को क्यों संशोधित किया जा सकता है?




c++11 initialization (3)

Songyuanyao के महान जवाब में जोड़ना, यदि आप एक कास्ट डेटा सदस्य चाहते हैं जिसे आप एक निर्माता में शुरू नहीं कर सकते हैं, तो आप सदस्य को static बना सकते हैं:

struct Bar {
    static const int b = 5; // static member initialization
    Bar(int c)
        :b(c)        // Error: static data member can only be initialized at its definition
    {
        b = c;       // Error: b is read-only
    }
};

C ++ 17 में आप इसे inline बनाकर इसमें और सुधार कर सकते हैं:

struct Bar {
    inline static const int b = 5; // static member initialization
    Bar(int c)
        :b(c)        // Error: static data member can only be initialized at its definition
    {
        b = c;       // Error: b is read-only
    }
};

इस तरह आपको ODR से कोई समस्या नहीं होगी।

https://code.i-harness.com

मैं उत्सुक हूं कि कंस्ट्रक्टर में कॉन्स्टेबल सदस्यों को क्यों संशोधित किया जा सकता है।

क्या आरंभीकरण में कोई मानक नियम है जो किसी सदस्य के "कास्ट-नेस" से आगे निकल जाता है?

struct Bar {
    const int b = 5; // default member initialization
    Bar(int c):b(c) {}
};

Bar *b = new Bar(2); // Problem: Bar::b is modified to 2
                     // was expecting it to be an error

कोई विचार?


जब तुम करोगे:

struct Bar {
    const int b = 5; // default member initialization
    ...
};

आप कंपाइलर को डिफॉल्ट कंस्ट्रक्टर के साथ ऐसा करने के लिए कह रहे हैं:

...
Bar() : b(5) 
{}
...

भले ही आपने डिफ़ॉल्ट कंस्ट्रक्टर प्रदान किया हो या नहीं। जब आप डिफ़ॉल्ट-निर्माता और प्रारंभिक असाइनमेंट प्रदान करते हैं, तो आप कंपाइलर के डिफ़ॉल्ट असाइनमेंट कोड (यानी b(5) ) को ओवरराइड करते हैं। घोषणा पर डिफ़ॉल्ट आरंभीकरण / असाइनमेंट उपयोगी है जब आपके पास कई निर्माता हैं, और आप सभी निर्माणकर्ताओं में कांस्ट सदस्यों को असाइन या नहीं कर सकते हैं:

...
Bar() = default; // b=5
Bar(int x) : b(x) // b=x
Bar(double y) : /*other init, but not b*/  // b=5
...

यह संशोधन (या असाइनमेंट) नहीं है, लेकिन initialization । जैसे

struct Bar {
    const int b = 5; // initialization (via default member initializer)
    Bar(int c)
        :b(c)        // initialization (via member initializer list)
    {
        b = c;       // assignment; which is not allowed
    }
};

const डेटा सदस्य को संशोधित या असाइन नहीं किया जा सकता है, लेकिन इसे सदस्य इनिशिएटिव सूची या डिफ़ॉल्ट सदस्य इनिशियलाइज़र के माध्यम से आरंभ किया जा सकता है (और इसकी आवश्यकता है)।

यदि एक ही डेटा सदस्य पर डिफ़ॉल्ट सदस्य initializer और सदस्य initializer दोनों प्रदान किए जाते हैं, तो डिफ़ॉल्ट सदस्य प्रारंभकर्ता को अनदेखा किया जाएगा। इसीलिए b->b का मूल्य 2 से आरंभ किया जाता है।

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

दूसरी ओर, डिफॉल्ट मेंबर इनिशियलाइज़र तभी प्रभावी होता है, जब मेंबर इनिशियलाइज़र लिस्ट में डेटा मेंबर निर्दिष्ट नहीं होता है। जैसे

struct Bar {
    const int b = 5;   // default member initialization
    Bar(int c):b(c) {} // b is initialized with c
    Bar() {}           // b is initialized with 5
};






const