2009-04-24 21 views
62

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

class MyClass 
{ 
. 
. 
. 
} MyInstance; 

संपादित बातें करते है: मैं इसे structs और enums के लिए देखने के एक सी अनुकूलता बिंदु से मिलता है, लेकिन मुझे लगता है कि जब से कक्षाएं सी भाषा का हिस्सा नहीं हैं यह मुख्य रूप से वहाँ रहते है समान घोषणा संरचनाओं के बीच स्थिरता। जो कुछ मैं ढूंढ रहा था वह कुछ भी बदलने में सक्षम होने के बजाय डिजाइन तर्क से अधिक था, हालांकि एक अच्छा कोड पूरा करने वाला आईडीई संकलन से पहले इसे फंस सकता है।

+4

यह मदद कर सकता है: http://www.cpptalk.net/confused-about-the-meaning-of-the-semicolon-vt11965.html –

+0

@Michael, धन्यवाद लिंक के लिए। एक ऐतिहासिक परिप्रेक्ष्य से यह अच्छी समझ में आता है, और यदि सी ++ सभी सी व्याकरण की अनुमति देता है, और सी ++ कक्षाएं structs के साथ समरूप हैं, तो हमें कक्षा के अंत में आवश्यक अर्ध-कॉलन के साथ छोड़ दिया जाता है। –

+3

@ ब्रायन, यूप गंभीर सवाल। मुझे अच्छी तरह से पता है कि मुझे इसके साथ रहना है, लेकिन मैं डिजाइन और कार्यान्वयन के पीछे तर्क के बारे में उत्सुक हूं। –

उत्तर

38

भाषा द्वारा एक प्रकार की घोषणा में समापन ब्रेस के बाद सेमी-कोलन आवश्यक है। सी

के शुरुआती संस्करणों के बाद से यह वही तरीका रहा है और हां, लोग वास्तव में उस घोषणा को करते हैं जो आपने अभी वहां रखा है। विधियों के अंदर स्कॉप्ड प्रकार बनाने के लिए यह उपयोगी है।

void Example() { 
    struct { int x; } s1; 
    s1.x = 42; 

    struct ADifferentType { int x; }; 
} 

इस मामले में, मुझे लगता है कि यह स्पष्ट है कि अर्ध-कॉलन की आवश्यकता क्यों है। हेडर फ़ाइल में घोषित करने के अधिक सामान्य मामले में इसकी आवश्यकता क्यों है, मैं अनिश्चित हूं। मेरा अनुमान यह है कि यह ऐतिहासिक है और संकलक को आसान बनाने के लिए किया गया था।

+0

मैं MyInstance निर्दिष्ट किए बिना स्कॉप्ड प्रकार क्यों नहीं बना सकता? यह अजीब लगता है क्योंकि आप दो क्रियाओं को जोड़ते हैं: नए प्रकार की घोषणा करना और नए चर घोषित करना। –

+0

@ मिकोला आप दोनों कर सकते हैं। नमूना देखें मैंने – JaredPar

15

मुझे लगता है कि यह इसलिए है क्योंकि वर्ग घोषणाएं हैं, भले ही उन्हें समूह के लिए ब्रेसिज़ की आवश्यकता हो। और हाँ, वहाँ ऐतिहासिक तर्क यह है कि सी में जब से तुम कर सकते हो

struct 
{ 
    float x; 
    float y; 
} point; 

आप सी में चाहिए ++ के समान बात करने में सक्षम हो है, यह class घोषणा उसी तरह से व्यवहार करने के लिए के लिए समझ में आता है।

7

यह के लिए

class MyClass 
{ 
. 
. 
. 
}; 

// instance declaration 
MyClass MyInstance; // semicolon here 

अर्धविराम के बाद वर्ग घोषणा के घुंघराले ब्रेसिज़ वास्तव में overkill है कम है, लेकिन यह कैसे सी ++ परिभाषित किया गया है है। परिवर्तनीय घोषणा के बाद अर्धविराम हमेशा आवश्यक है और समझ में आता है।

+0

जोड़ा, तो क्या प्रत्येक घोषणा के बाद सी ++ को सेमी-कोलन की आवश्यकता होती है? –

+0

ध्यान दें कि, इस तरह, आप किसी अज्ञात वर्ग का ऑब्जेक्ट नहीं बना सकते हैं, जबकि आप दूसरी तरफ कर सकते हैं। – Kevin

2

मैं ऐसे घोषणाओं

class MyClass 
{ 
. 
. 
. 
} MyInstance; 

का उपयोग नहीं करते लेकिन इस मामले में मैं समझ सकता क्यों अर्धविराम है।
क्योंकि यह int a; - परिवर्तनीय घोषणा की तरह है।

संभवतः स्थिरता के लिए आप 'माइइंस्टेंस' अर्धविराम को छोड़ सकते हैं।

2

यह संगतता कारणों के लिए एक struct के बाद की जरूरत है, और कैसे आप इस तरह होगा:

struct MyStruct { ... }; 
class MyClass { ... } //inconsistency 
2

C/C++ में; एक बयान टर्मिनेटर है। सभी कथन समाप्त कर दिए गए हैं; अस्पष्टता से बचने के लिए (और पार्सिंग को सरल बनाने के लिए)। व्याकरण इस संबंध में सुसंगत है। भले ही कक्षा घोषणा (या उस मामले के लिए कोई भी ब्लॉक) कई लाइनें लंबी है और {} के साथ सीमित है {} यह अभी भी एक कथन है ({} कथन का हिस्सा है) इसलिए इसे समाप्त करने की आवश्यकता है;

अपने उदाहरण में

class MyClass{...} MyInstance; 

पूरा बयान है, (एक विभाजक/delimitor नहीं है)।

int a, b, c; 

कारण एक नहीं करता है: एक एक सिंगल स्टेटमेंट

class MyClass{...} MyInstance1, MyInstance2; 

यह एक एकल बयान में एक आदिम प्रकार के कई उदाहरण घोषित करने के साथ पूरी तरह से संगत है में घोषित वर्ग के कई उदाहरण निर्धारित कर सकते हैं अक्सर कक्षा और उदाहरण के इस तरह के विलुप्त होने को देखते हैं, उदाहरण क्या हो सकता है? केवल? एक वैश्विक चर हो, और आप वास्तव में वैश्विक वस्तुओं को अक्सर नहीं चाहते हैं जब तक कि वे स्थैतिक और/या सादे पुराने डेटा संरचनाएं न हों।

+0

लेकिन फ़ंक्शन परिभाषा भी एक कथन है लेकिन अर्धविराम के बिना। –

39

@MichaelHeran द्वारा प्रदत्त linkरूट कारण प्रदान करता है। अर्धविराम (जैसा कि अन्य ने बताया है) सी से विरासत में मिला है लेकिन यह स्पष्ट नहीं करता है कि सी ने इसे पहले स्थान पर क्यों इस्तेमाल किया। चर्चा एक उदाहरण के इस मणि में शामिल हैं: जब तक अन्यथा घोषित सी के

struct fred { int x; long y; }; 
main() 
{ 
    return 0; 
} 

पुराने संस्करण एक समारोह से एक अंतर्निहित पूर्णांक वापसी प्रकार था। यदि हम संरचना परिभाषा के अंत में ; को छोड़ देते हैं, तो हम न केवल एक नया प्रकार fred परिभाषित कर रहे हैं, बल्कि यह भी घोषित करते हैं कि main()fred का उदाहरण लौटाएगा। अर्थात। कोड इस तरह पार्स किया जाएगा:

struct fred { int x; long y; } main() 
{ 
    return 0; /* invalid return type, expected fred type */ 
} 
+4

यह स्वीकार्य उत्तर होना चाहिए। – nikoliazekter

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