2011-11-21 9 views
14

N2628 से संबंधित, गैर स्थैतिक डेटा सदस्य प्रारंभकर्ताओं को स्पष्ट रूप से परिभाषित रचनाकारों द्वारा ओवरराइड किया जा सकता है, लेकिन यह स्पष्ट रूप से परिभाषित प्रतिलिपि निर्माता के बारे में थोड़ा अस्पष्ट प्रतीत होता है।सी ++ 0x में, गैर स्थैतिक डेटा सदस्य प्रारंभकर्ता निहित प्रतिलिपि निर्माता को ओवरराइड करते हैं?

विशेष रूप से, मैंने देखा है कि ऐप्पल क्लैंग संस्करण 3.0 के साथ, व्यवहार इस बात पर निर्भर करता है कि संरचना (या कक्षा) एक पीओडी है या नहीं।

निम्नलिखित प्रोग्राम आउटपुट "1" देता है, जो इंगित करता है कि कॉपी-कन्स्ट्रक्टर दाएं हाथ की तरफ अनदेखा कर रहा है, और इसके बजाय नए गैर स्थैतिक डेटा सदस्य प्रारंभकर्ता को प्रतिस्थापित कर रहा है (इस उदाहरण में, बूलियन के लिए सही मूल्य एक्स :: क)।

#include <iostream> 
#include <string> 

struct X 
{ 
    std::string string1; 
    bool a = true; 
}; 

int main(int argc, char *argv[]) 
{ 
    X x; 
    x.a = false; 
    X y(x); 
    std::cout << y.a << std::endl; 
} 

हालांकि, संदेहास्पद रूप से यदि आप string1 बाहर टिप्पणी:

// std::string string1; 

तो व्यवहार में काम करता है के रूप में मैं उम्मीद, शायद कोई परोक्ष उत्पन्न क्योंकि वहाँ है कॉपी-निर्माता (उत्पादन "0" है) , और इसलिए डेटा कॉपी किया गया है।

क्या सी ++ 0x विनिर्देश वास्तव में सुझाव देता है कि अंतर्निहित परिभाषित प्रति-निर्माता को पर दाएं हाथ की सामग्री की प्रतिलिपि बनाने का अच्छा विचार है? क्या वह कम उपयोगी और अनजान नहीं है? मुझे गैर स्थैतिक सदस्य प्रारंभकर्ता कार्यक्षमता काफी सुविधाजनक होने के लिए मिलती है, लेकिन यदि यह सही व्यवहार है, तो मैं इसके कठिन और अनजान व्यवहार के कारण स्पष्ट रूप से सुविधा से बचूंगा।

कृपया मुझे बताएं कि मैं गलत हूं?

अद्यतन: यह बग क्लैंग स्रोत भंडार में तय किया गया है। यह revision देखें।

अद्यतन: यह बग ऐप्पल क्लैंग संस्करण 3.1 (टैग/ऐप्पल/क्लैंग -318.0.45) (एलएलवीएम 3.1 एसवीएन पर आधारित) में तय होता है। क्लैंग के इस संस्करण को शेर के लिए एक्सकोड 4.3 के हिस्से के रूप में वितरित किया गया था।

+0

+1 नेबुलोसिटी –

उत्तर

10

यह सब के बाद, मानकों अंश का प्रकाश डाला भागों को देखने के छायादार नहीं है:

डिफॉल्ट की कॉपी/कदम कंस्ट्रक्टर्स (§ 12.8) पर अनुभाग यह संपूर्णता में उद्धृत करने के लिए थोड़ा बहुत लंबा है। कम नीचे कि initializers के साथ गैर स्थिर सदस्य खेतों अभी भी बस § 12.8 डिफॉल्ट की कॉपी/कदम निर्माता

से कॉपी कर रहे हैं है:

-6। गैर-यूनियन क्लास एक्स के लिए अंतर्निहित रूप से परिभाषित प्रतिलिपि/चालक कन्स्ट्रक्टर इसके आधार और सदस्यों के सदस्यवार प्रतिलिपि/ को निष्पादित करता है। [ Note: brace-or-equal-initializers of non-static data members are ignored. See also the example in 12.6.2. —end note ] प्रारंभिकरण का क्रम आधार के के आधार और उपयोगकर्ता द्वारा परिभाषित कन्स्ट्रक्टर में सदस्यों के क्रम के समान है (12.6.2 देखें)। एक्स को या तो कन्स्ट्रक्टर का पैरामीटर दें या, चालक के लिए, पैरामीटर का जिक्र करते हुए एक xvalue के लिए।प्रत्येक आधार या गैर स्थिर डेटा सदस्य नकल की जाती है/तरीके अपने प्रकार के लिए उपयुक्त में ले जाया गया:

  • यदि सदस्य एक सरणी है, प्रत्येक तत्व सीधे-प्रारंभ एक्स की इसी subobject साथ है;
  • यदि कोई सदस्य एम में Rvalue संदर्भ प्रकार T & & है, तो यह static_cast (x.m) के साथ प्रत्यक्ष-प्रारंभ होता है;
  • अन्यथा, आधार या सदस्य प्रत्यक्ष आधार या एक्स के सदस्य के साथ प्रत्यक्ष-प्रारंभिक है।

    struct A { 
        int i = /* some integer expression with side effects */; 
        A(int arg) : i(arg) { } 
        // ... 
    }; 
    

    ए (int) निर्माता:
    आभासी आधार वर्ग subobjects

यह करने के लिए भेजा नमूना है परोक्ष परिभाषित कॉपी/कदम निर्माता द्वारा केवल एक बार प्रारंभ किया जाएगा मैं केवल तर्क के मूल्य को आरंभ कर दूंगा, और मेरे ब्रेस-या-बराबरिनिज़र में साइड इफेक्ट्स नहीं होंगे। —end example ]


पूर्णता के लिए, डिफॉल्ट की डिफ़ॉल्ट निर्माता पर इसी अनुभाग:

§ 12,1

-6। डिफॉल्ट कन्स्ट्रक्टर जिसे डिफॉल्ट किया गया है और हटाए गए रूप में परिभाषित नहीं किया गया है, यह odr-used (3.2) है, जो इसके वर्ग प्रकार (1.8) का ऑब्जेक्ट बनाने के लिए या जब इसकी पहली घोषणा के बाद स्पष्ट रूप से डिफॉल्ट किया गया हो।
निहित रूप से परिभाषित डिफ़ॉल्ट कन्स्ट्रक्टर कक्षा के प्रारंभिकरणों का सेट करता है जो उस श्रेणी के लिए उपयोगकर्ता द्वारा लिखित डिफ़ॉल्ट कन्स्ट्रक्टर द्वारा कोई सीटीओ-प्रारंभकर्ता (12.6.2) और खाली यौगिक-कथन के साथ किया जाएगा। यदि वह उपयोगकर्ता लिखित डिफ़ॉल्ट कन्स्ट्रक्टर खराब हो जाएगा, तो कार्यक्रम खराब हो गया है।
यदि उपयोगकर्ता द्वारा लिखित डिफ़ॉल्ट कन्स्ट्रक्टर एक कॉन्सएक्सप्रक्टर कन्स्ट्रक्टर (7.1.5), की आवश्यकताओं को पूरा करेगा, तो निश्चित रूप से परिभाषित डिफ़ॉल्ट कन्स्ट्रक्टर constexpr है। कक्षा के लिए डिफॉल्ट डिफॉल्ट कन्स्ट्रक्टर से पहले, निश्चित रूप से परिभाषित किया गया है, सभी गैर-उपयोगकर्ता द्वारा प्रदत्त डिफॉल्ट कन्स्ट्रक्टर अपने बेस क्लास और इसके nonstatic डेटा सदस्यों को स्पष्ट रूप से परिभाषित किया गया होगा। [नोट: एक निहित रूप से घोषित डिफ़ॉल्ट कन्स्ट्रक्टर में अपवाद-विनिर्देश (15.4) है।
एक स्पष्ट रूप से डिफॉल्ट परिभाषा में एक अंतर्निहित अपवाद-विनिर्देश हो सकता है, 8.4 देखें। —end note ]

+0

दिलचस्प के लिए +1। क्या यह डिफ़ॉल्ट _copy-constructor_ के संदर्भ में है? –

+0

ऐसा लगता है कि केवल डिफॉल्ट कन्स्ट्रक्टर, AFAIK का संदर्भ है जो कि 0 तर्क लेने वाले निर्माता हैं। – Kleist

+0

यह संदर्भ * डिफॉल्ट कन्स्ट्रक्टर * * प्रतिलिपि कन्स्ट्रक्टर * –

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

  • कोई संबंधित समस्या नहीं^_^