2011-07-19 18 views
10

मैं सी ++ के लिए एक ट्यूटोरियल पढ़ रहा हूं लेकिन वास्तव में यह मुझे दोनों के बीच एक अंतर (वाक्यविन्यास के अलावा) नहीं देता था। ट्यूटोरियल से उद्धरण यहां दिया गया है।स्पष्टीकरण असाइनमेंट बनाम नकली असाइनमेंट

आप घोषणा पर अपने चर के मूल्य भी असाइन कर सकते हैं।

int nValue(5); // implicit assignment 

:

int nValue = 5; // explicit assignment 

तुम भी एक अंतर्निहित काम का उपयोग कर चर को मान निर्दिष्ट कर सकते हैं: जब हम एक चर असाइनमेंट ऑपरेटर का उपयोग करने के मूल्यों ( बराबर चिह्न) आवंटित , यह एक स्पष्ट काम कहा जाता है भले ही निहित असाइनमेंट फ़ंक्शन कॉल की तरह दिखते हैं, कंपाइलर ट्रैक करता है कि कौन से नाम चर हैं और फ़ंक्शंस हैं ताकि उन्हें ठीक से हल किया जा सके।

क्या कोई अंतर है? क्या एक दूसरे पर अधिक पसंद है?

+5

यह एक घोषणा नहीं है, इसकी परिभाषा है। उस ट्यूटोरियल को हटाएं और [एक सभ्य पुस्तक पढ़ें] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)। सी ++ में सोच मुफ्त है और लेखक के पेज से उपलब्ध है। –

+3

@ कैट प्लस प्लस: यह एक परिभाषा है, लेकिन इसका मतलब यह नहीं है कि यह घोषणा नहीं है। –

+1

@JamesMcNellis: यह एक ट्यूटोरियल होना चाहिए और कॉलिंग परिभाषा घोषणाएं दोनों के बीच भ्रम से छुटकारा पाने में मदद नहीं करती हैं। शायद मैं आज सिर्फ क्रैकी हूँ। : पी –

उत्तर

10

पहले को प्राचीन प्रकारों जैसे int के साथ प्राथमिकता दी जाती है; दूसरे प्रकार के जिनके साथ एक कन्स्ट्रक्टर है, क्योंकि यह कन्स्ट्रक्टर को स्पष्ट करता है।

जैसे, आपके द्वारा निर्धारित करता है, तो एक class Foo एक भी int से निर्माण किया जा सकता है कि, तो

Foo x(5); 

Foo x = 5; 

से अधिक पसंद किया जाता है (आप पूर्व वाक्य रचना वैसे भी जब से अधिक की आवश्यकता एक तर्क पारित किया जाता है, जब तक कि आप Foo x = Foo(5, "hello"); का उपयोग न करें जो सादा बदसूरत है और operator= जैसा दिखता है।)

+4

उल्लेखनीय है कि निर्माण वाक्यविन्यास के साथ, आपको सबसे अधिक परेशान पार्स के बारे में सावधान रहना होगा। –

+4

यह भी ध्यान दें कि 'Foo x = 5' केवल तभी काम करेगा यदि' Foo :: Foo (int) 'को' स्पष्ट 'चिह्नित नहीं किया गया है। – Vitus

+0

... (@Vitus टिप्पणी के साथ जारी है) और 'Foo' प्रतिलिपि निर्माता उपलब्ध है। –

1

जब आप एक परिवर्तनीय घोषणा करते हैं और इसे प्रारंभ करते हैं, तो वे उस संदर्भ में कार्यात्मक रूप से समान होते हैं। मैं आमतौर पर के रूप में दो का संदर्भ लें:

int nValue = 5; // assignment syntax 

और

int nValue(5); // construction syntax 

बुनियादी प्रकार के लिए, मैं निर्माण से अधिक काम पसंद करते हैं क्योंकि यह विशेष रूप से जो लोग अन्य भाषाओं में प्रोग्राम है, और अधिक प्राकृतिक है।

कक्षा प्रकारों के लिए, मैं निर्माण वाक्यविन्यास पसंद करता हूं क्योंकि यह एक कन्स्ट्रक्टर फ़ंक्शन के अस्तित्व को रोकता है।

+1

मानक (एन 3242) वाक्यविन्यास 'टी एक्स = ए' * प्रति-प्रारंभिकरण * और 'टी एक्स (ए)' * प्रत्यक्ष-प्रारंभिक * कहता है। दोनों कन्स्ट्रक्टर 'टी :: टी (ए) 'का आह्वान करने के वैध तरीके हैं। –

5

आदिम प्रकार दोनों के बराबर हैं, यह उपयोगकर्ता परिभाषित वर्ग प्रकारों के लिए है कि एक अंतर है। दोनों मामलों में जो कोड निष्पादित हो जाता है वह वही होगा (मूल अनुकूलन के बाद), लेकिन प्रकारों की आवश्यकताएं अलग-अलग होती हैं यदि हम जिस तत्व से प्रारंभ कर रहे हैं वह उस प्रकार का नहीं है जिसे हम बना रहे हैं।

कॉपी-प्रारंभ (T t = u;) प्रकार T कि परोक्ष t को u से बदल दिया गया है की एक अस्थायी से निर्माण कॉपी करने के लिए बराबर है। दूसरी तरफ प्रत्यक्ष-प्रारंभिक उचित कन्स्ट्रक्टर को सीधे कॉल के बराबर है।

जबकि अधिकांश परिस्थितियों में कोई अंतर नहीं होगा, अगर निर्माता कि u लेता explicit घोषित किया जाता है या यदि कॉपी-निर्माता दुर्गम है, तो कॉपी-प्रारंभ असफल हो जायेगी:

struct A { 
    explicit A(int) {} 
}; 
struct B { 
    B(int) {} 
private: 
    B(B const &); 
}; 
int main() { 
    A a(1);  // ok 
    B b(1);  // ok 
// A a2 = 1; // error: cannot convert from int to A 
// B b2 = 1; // error: B(B const &) is not accessible 
} 

कुछ ऐतिहासिक पृष्ठभूमि के लिए, प्रारंभिक रूप से आदिम प्रकारों को प्रति-प्रारंभिक के साथ शुरू किया जाना था। जब * कक्षा से सदस्य विशेषताओं को प्रारंभ करने के लिए प्रारंभकर्ता-सूची * एस को भाषा में जोड़ा गया था, तो यह निर्णय लिया गया था कि आदिम प्रकारों को उसी वाक्यविन्यास के साथ प्रारंभ किया जाना चाहिए जो कक्षाओं को प्रारंभकर्ता सूची वर्दी और सरल में वाक्यविन्यास रखने के लिए किया जाना चाहिए। साथ ही प्रति-प्रारंभिक के माध्यम से कक्षाओं के प्रारंभिकरण की अनुमति देने से उपयोगकर्ता परिभाषित प्रकारों को आदिम प्रकारों के करीब बना दिया जाता है। दो प्रारंभिक प्रारूपों में अंतर स्वाभाविक रूप से आता है: int a = 5.0; को 5.0 से int पर रूपांतरण के रूप में संसाधित किया जाता है, और उसके बाद int से प्रारंभ होता है। उपयोगकर्ता परिभाषित प्रकारों के साथ ही जाता है: T u = v; को v से T पर रूपांतरण के रूप में संसाधित किया जाता है, और फिर उस परिवर्तित मूल्य से u का निर्माण प्रतिलिपि बनाएँ।

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