2009-05-29 17 views
16

मैं एक सी ++ शुरुआत कर रहा हूं, इसलिए क्षमा करें यदि प्रश्न बहुत बुनियादी है।सी ++ खाली स्ट्रिंग कन्स्ट्रक्टर

मैंने स्ट्रिंग constrcturs एकत्र करने की कोशिश की है और उन सभी को आजमाएं (उन्हें याद करने के लिए)।

string strA();   // string(); empty string // incorrect 
string strB("Hello"); // string(const char* str) 
string strC("Hello",3); // string(const char* str, size_type length) 
string strD(2,'c');  // string(size_type lenght, const char &c) 
string strE(strB);  // string(const string& s) 

cout << strA << endl; 
cout << strB << endl; 
cout << strC << endl; 
cout << strD << endl; 
cout << strE << endl; 

वे सब के सब Stra के लिए छोड़कर काम करता है। यह "1" प्रिंट करता है। क्यों? इस मामले में stra का प्रकार क्या है? जब मैं अनिश्चित हूं तो मैं सामान के प्रकार की जांच कैसे कर सकता हूं?

मैंने ध्यान दिया है सही तरीका यह है कि (जो वैसे, अन्य निर्माताओं के साथ असंगत प्रतीत होता है कभी कभी कभी कभी कोष्ठक कोई कोष्ठक):

string strA; 

ps: बोल्ड, हमेशा की तरह अप्रासंगिक में प्रश्न जवाब कम हो जाएगा।

उत्तर

32

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

string strA(); 

string strA(void); 

नो आर्ग समारोह जो स्ट्रिंग रिटर्न के एक प्रोटोटाइप के बराबर है।

आप स्पष्ट रूप से कॉल करना चाहते हैं, तो कोई आर्ग निर्माता इस प्रयास करें:

string strA=string(); 

यह पूरी तरह से बराबर नहीं है - यह 'कोई आर्ग निर्माता का उपयोग कर एक अस्थायी स्ट्रिंग बनाने का मतलब है और फिर कॉपी यह चर प्रारंभ करने में strA ', लेकिन संकलक को इसे अनुकूलित करने और प्रतिलिपि बनाने की अनुमति है।

संपादित करें: Here is an appropriate item in C++ FAQ Lite

+3

और यह एक कारण है कि मैंने सी ++ का उपयोग करना बंद कर दिया। –

+3

@ डायट्रिच एपीपी: इससे मुझे भी परेशान किया गया। मुझे लगता है कि यह सी संगतता रखने के लिए भुगतान किया गया मूल्य है। विकल्प सी का उपयोग कर रहा है, जिसमें इसकी मीट्रिक टन समस्याएं हैं, मेरा अनुमान है कि सी ++ रखना और उस पतन से बचना बेहतर है। – paercebal

+0

'std :: string stra (" ") के बारे में कैसे;' – CaptainDaVinci

13

यह एक समारोह घोषणा के रूप में

string strA(); 

समझता है।

डिफ़ॉल्ट निर्माता उपयोग के लिए:

string strA; 
+2

ढेर को आवंटित करते समय आप उस नोटेशन का उपयोग कर सकते हैं: स्ट्रिंग * strA = new string(); – Skilldrick

6

सी ++ में, सी के रूप में, वहाँ एक नियम का कहना है कि कुछ भी है कि एक declarartion की तरह दिखता है एक घोषणा के रूप में इलाज किया जाएगा।

string strA(); 

फ़ंक्शन घोषणा की तरह दिखता है, इसलिए इसे एक के रूप में माना जाता है। आप की जरूरत है:

string strA; 
1

संकलक एक समारोह जो शून्य तर्क लेता है और स्ट्रिंग प्रकार का ऑब्जेक्ट देता है के एक समारोह प्रोटोटाइप के रूप में string strA() व्याख्या करता है। यदि आप एक खाली स्ट्रिंग ऑब्जेक्ट बनाना चाहते हैं string strA; (पैराथेसिस के बिना)

3

यह 1 क्योंकि कार्यों के लिए संकेत हमेशा true के रूप में सांख्यिक में बदल दिए जाते प्रिंट करता है।

+5

केवल तभी जब पॉइंटर कार्य करना गैर-शून्य है। वैसे भी, कार्य करने के लिए एक सूचक को इसकी परिभाषा को इंगित करना चाहिए, और यह यहां गायब है। यह लिंक नहीं होना चाहिए था। – MSalters

2

tkopec सही है कि यह क्यों काम नहीं करता है। अपने दूसरे सवाल का जवाब करने के लिए, आप निम्न तरीके से प्रकार की जांच है:

template<typename TEST> void Error_() { 
    TEST* MakeError = 1; 
} 

Error_(StrA); बुला कर आप एक संकलन त्रुटि प्राप्त होगी, और अपने संकलक शायद आपको बता देंगे कि यह अब Error_< std::basic_string<char, std::allocator<char> > (*)(void)>(std::basic_string<char, std::allocator<char> > (*)(void)) में हुआ, std :: basic_string> बस std :: स्ट्रिंग है, इसलिए इसका वास्तव में Error_< std::string (*)(void)> (std::string (*)(void)) है। '<>' के बीच का हिस्सा '()' के बीच दोहराया गया है, और यह strA का sype है। इस मामले में, std::string (*)(void)

+0

strA का प्रकार एक फ़ंक्शन है। std :: स्ट्रिंग (शून्य)। यह एक फ़ंक्शन पॉइंटर नहीं है। उसे इसे स्ट्रिंग (* strA)() के रूप में घोषित करना होगा; अगर वह एक फंक्शन पॉइंटर बनना चाहता था।मुझे शायद पता चलेगा कि आपका क्या मतलब है, लेकिन आपके आखिरी वाक्यों की तरह लगता है कि यह एक फंक्शन पॉइंटर है। –

4

मुझे नहीं लगता कि इस मामले में, नियम "अगर यह घोषणा हो सकती है, तो इसे एक घोषणा के रूप में लिया जाता है" लागू होता है। निम्नलिखित में के बाद से, दोनों बातें घोषणाओं

string a; 
string a(); 

एक एक वस्तु की घोषणा है, और अन्य एक समारोह की घोषणा है। नियम अन्य मामलों में लागू होता है। उदाहरण के लिए, इस मामले में:

string a(string()); 

उस मामले में, string() दो बातें हो सकता है। एक अनाम समारोह पैरामीटर के

  • घोषणा
  • अभिव्यक्ति एक डिफ़ॉल्ट बनाने का निर्माण string

फुले यहाँ लागू होता है, और string() निम्नलिखित रूप में एक ही मतलब करने के लिए लिया जाता है, नामित पैरामीटर (नाम अप्रासंगिक हैं फ़ंक्शन घोषित करते समय पैरामीटर में)

string a(string im_not_relevant()); 

यदि कोई फ़ंक्शन पैरामीटर के रूप में एक सरणी या एनीट लेता है उसका कार्य, वह पैरामीटर एक सूचक में decays। फ़ंक्शन पैरामीटर के मामले में, फ़ंक्शन पर पॉइंटर के लिए। इस प्रकार, यह निम्न में से अधिक परिचित

string a(string (*im_not_relevant)()); 

लेकिन आपके मामले में, यह नहीं बल्कि वाक्य रचना कि जिस तरह से में हो रही है लग सकता है के बराबर है। यह कह रहा है कि निम्नलिखित एक समारोह घोषणा है। यह कभी नहीं एक वस्तु की घोषणा हो सकती है (हालांकि कि शायद प्रोग्रामर द्वारा इरादा था!) ​​

string a(); 

तो वहाँ पहली जगह में इस संदर्भ में कोई अस्पष्टता नहीं है, और इस तरह यह एक समारोह की घोषणा की। चूंकि string में उपयोगकर्ता ने कन्स्ट्रक्टर को परिभाषित किया है, तो आप केवल कोष्ठक को छोड़ सकते हैं, और प्रभाव वही रहता है जो इरादा था।

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