क्या यह एक पुराना C ++ स्टाइल कंस्ट्रक्टर है?


17

यहाँ C ++ कोड का एक टुकड़ा।

इस उदाहरण में, कई कोड ब्लॉक कंस्ट्रक्टर कॉल की तरह दिखते हैं। दुर्भाग्य से, ब्लॉक कोड # 3 नहीं है (आप इसे https://godbolt.org/z/q3rsxn का उपयोग करके जांच सकते हैं और https://cppinsights.io )।

मुझे लगता है, यह एक पुराना C ++ संकेतन है और यह {} (cf # 4) का उपयोग करके नए C ++ 11 निर्माण संकेतन की शुरूआत की व्याख्या कर सकता है।

क्या आपके पास T(i)अर्थ के लिए स्पष्टीकरण है, इसलिए एक निर्माण संकेतन के करीब है, लेकिन निश्चित रूप से इतना अलग है?

struct T {
   T() { }
   T(int i) { }
};

int main() {
  int i = 42;
  {  // #1
     T t(i);     // new T named t using int ctor
  }
  {  // #2
     T t = T(i); // new T named t using int ctor
  }
  {  // #3
     T(i);       // new T named i using default ctor
  }
  {  // #4
     T{i};       // new T using int ctor (unnamed result)
  }
  {  // #5
     T(2);       // new T using int ctor (unnamed result)
  }
}

NB: इस प्रकार, T(i)(# 3) के बराबर है T i = T();


1
मुझे लगता है कि आपके सभी कथन सही हैं।
Arne J


ध्यान दें कि संकलक आपको बहुत कुछ बताएगा जो आपको जानना जरूरी है यदि आप इसे पूछते हैं: जोड़ें -Wallऔर आपको " warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'i' [-Wvexing-parse]" क्लैंग से, या जीसीसी से थोड़ा कम प्रेरित " warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]" मिलता है
मैक्स लैंगहॉफ

@QuentinUK इस लिंक के लिए धन्यवाद। मैं कार्यों के बारे में इसके बारे में जानता था (उदाहरण के लिए T t()) लेकिन इतनी सरल घोषणा अभिव्यक्तियों के लिए नहीं। यकीन के लिए, यह अप्रिय हो सकता है ।
पास्कल एच।

जवाबों:


17

बयान:

T(i);

के बराबर है:

T i;

दूसरे शब्दों में, यह iप्रकार के साथ नामित एक चर घोषित करता है T। ऐसा इसलिए है क्योंकि कुछ स्थानों पर घोषणाओं में कोष्ठकों को अनुमति दी जाती है (घोषणाओं के बंधन को बदलने के लिए) और चूंकि इस बयान को घोषणा के रूप में पार्स किया जा सकता है, यह एक घोषणा है (भले ही यह अभिव्यक्ति के रूप में अधिक समझ में आता हो)।


तो, क्या यह केवल एक व्याख्या विकल्प है जो सी विनिर्देशों से विरासत में मिला है जहां int(i)एक intनाम भी घोषित किया गया है i?
पास्कल एच।

@PascalH। एक निश्चित दृष्टिकोण से, यह सच हो सकता है। स्ट्रॉस्ट्रप ने डी एंड ई में लिखा कि उन्होंने सी ++ के लिए एक वैकल्पिक, अधिक सहज घोषणा सिंटैक्स माना था। यदि C ++ को C के साथ पीछे की ओर संगत नहीं होना था, तो शायद इसके पास वैकल्पिक वाक्यविन्यास होगा, और इस प्रकार अभिव्यक्तियों के साथ संभावित अस्पष्टता से बचें।
ब्रायन

-1

असेम्बलर में क्या होता है यह देखने के लिए आप कंपाइलर एक्सप्लोरर का उपयोग कर सकते हैं ।

आप यह देख सकते हैं कि # 1, # 2 # 4 और # 5 एक ही काम करते हैं लेकिन अजीब तरह से # 3 दूसरे कंस्ट्रक्टर (बेस ऑब्जेक्ट कंस्ट्रक्टर) को कॉल करते हैं।

क्या किसी के पास स्पष्टीकरण है?

कोडर कोड:

::T() [base object constructor]:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        nop
        pop     rbp
        ret
T::T(int):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     DWORD PTR [rbp-12], esi
        nop
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 42
// #1
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-7]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #2
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-8]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #3
        lea     rax, [rbp-9]
        mov     rdi, rax
        call    T::T() [complete object constructor]
// #4
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-6]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #5
        lea     rax, [rbp-5]
        mov     esi, 2
        mov     rdi, rax
        call    T::T(int)

        mov     eax, 0
        leave
        ret
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.