2012-04-11 11 views
5

मैं कुछ सवाल है कि मैं सी के साथ ++ अनुभव किसी के लिए काफी आसान हो जाएगा लगता है कि मिल गया है जवाब देने के लिए, मैं बोल्ड हूँ टी एल के लिए quesitons; डॉसी शैली तार :: स्ट्रिंग रूपांतरण स्पष्टीकरण

क्यों stringTest में पैरामीटर चिह्नित किया जाना है करता स्थिरांक जब एक सी शैली स्ट्रिंग पारित कर दिया:

void stringTest(const std::string &s) 
{ 
    std::cout << s << std::endl; 
} 

int main() 
{ 
    stringTest("HelloWorld"); 
} 

Hopefuly किसी ने मेरे विचार प्रक्रिया यहाँ में त्रुटि का कहना कर सकते हैं:

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

इसके अलावा, क्या एक cstyle स्ट्रिंग निर्माता देखो की तरह, और कैसे संकलक देखने पर यह आह्वान करने के लिए पता है जाएगा:

stringTest("HelloWorld"); 

यह बस एक स्ट्रिंग शाब्दिक पहचान करता है एक चार की तरह कुछ होने के लिए * ?

कॉपी कन्स्ट्रक्टर का अध्ययन करते समय मैंने इन सवालों पर ठोकर खाई है। मेरे अपने स्पष्टीकरण के लिए एक और त्वरित quesiton ...

की तरह कुछ के मामले में:

std::string s = "HelloWorld"; 

cstyle स्ट्रिंग एक अस्थायी std :: स्ट्रिंग का दृष्टांत के लिए इस्तेमाल किया निर्माता, और फिर अस्थायी स्ट्रिंग है स्ट्रिंग कॉपी कन्स्ट्रक्टर का उपयोग करके "एस" में कॉपी किया गया?:

std::string(const std::string&); 
+0

"स्ट्रिंगटेस्ट में पैरामीटर को क्यों चिह्नित किया जाना चाहिए" - चाहे यह _necessary_ है, आप _all_ संदर्भ 'const' बनाना चाहते हैं जो वास्तव में संशोधित नहीं हैं। – leftaroundabout

+0

@ बाएंराउंडबाउट: उचित बिंदु, मैं निश्चित रूप से इसे दिल में ले जाऊंगा। – Riken

+0

संभावित डुप्लिकेट [कैसे एक गैर-कॉन्स्ट संदर्भ एक अस्थायी वस्तु से बंधे नहीं हो सकता है?] (Http://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to -ए-अस्थायी-ऑब्जेक्ट) –

उत्तर

2

क्यों stringTest में पैरामीटर स्थिरांक चिह्नित किया जाना है करता है जब एक सी शैली स्ट्रिंग पारित कर दिया?

यह केवल जब पैरामीटर, एक संदर्भ है के बाद से एक अस्थायी std::stringchar const* आप में पास से निर्माण किया है और एक अस्थायी करने के लिए एक गैर const संदर्भ गैर कानूनी है करने के लिए है।

क्या यह आसानी से एक स्ट्रिंग अक्षर को चार * की तरह कुछ पहचानता है?

एक स्ट्रिंग अक्षर char const सरणी है, जो char const* का क्षय होता है। उस से, कंपाइलर अनुमान लगाता है कि इसे अस्थायी बनाने के लिए गैर-explicit कन्स्ट्रक्टर std::string::string(char const *) का उपयोग करना चाहिए।

क्या कास्टाइल कन्स्ट्रक्टर एक अस्थायी std :: स्ट्रिंग को चालू करने के लिए उपयोग किया जाता है, और फिर अस्थायी स्ट्रिंग को स्ट्रिंग कॉपी कन्स्ट्रक्टर का उपयोग करके "एस" में कॉपी किया जाता है?

यह उससे थोड़ा अधिक जटिल है। हां, एक अस्थायी बनाया गया है। लेकिन कॉपी कन्स्ट्रक्टर को बुलाया जा सकता है या नहीं; संकलक को कॉपी निर्माण को ऑप्टिमाइज़ेशन के रूप में छोड़ने की अनुमति है।प्रतिलिपि निर्माता अभी भी प्रदान की जानी चाहिए, हालांकि, तो निम्नलिखित संकलन नहीं होगा:

class String { 
    String(char const *) {} 
    private: 
    String(String const &); 
}; 

int main() 
{ 
    String s = ""; 
} 

इसके अलावा, सी ++ 11 कदम निर्माता में उपयोग किया जाएगा, यदि प्रदान की; उस स्थिति में, कॉपी कन्स्ट्रक्टर की आवश्यकता नहीं है।

+0

+1 लेकिन आपको यह स्पष्ट करना चाहिए कि तीसरे मामले में, प्रतिलिपि बनाने वाला * आवश्यक * है, लेकिन वास्तव में यह नहीं कहा जाता है क्योंकि यह (हमेशा - अनुकूलन के बावजूद?) elided हो । यह अपेक्षाकृत महत्वपूर्ण है भले ही यह "बस" एक अनुमत अनुकूलन है। –

+0

एक स्ट्रिंग शाब्दिक में 'char const * 'नहीं है, यह' char const [N] 'है, जो निश्चित रूप से परिवर्तनीय रूप से परिवर्तनीय रूप से परिवर्तनीय है' char const *' –

+0

@ कोनराड रुडॉल्फ: क्या उसने प्रतिलिपि/चाल पर थोड़ा सा विस्तार किया कन्स्ट्रक्टर चीज –

0

const string & s इस उदाहरण में "HelloWorld" तर्क से निर्माता को आमंत्रित करने के लिए आवश्यक है। इस्तेमाल किया गया कन्स्ट्रक्टर टाइप-रूपांतरण निर्माण है।

string& s ऐसा नहीं करेगा क्योंकि एस सीधे स्ट्रिंग ऑब्जेक्ट का संदर्भ दे रहा है।

जैसे रूपांतरण एक typedef

typedef basic_string<char> string; 

साथ

basic_string(const _CharT* __s); 

को कुछ इसी तरह से परिभाषित किया गया है तो घोषणा

basic_string(const char * __s)  
+0

वह * लगता है * गलत। या तो आप गलत हैं या स्पष्टीकरण अस्पष्ट है। किसी भी तरह से, एक प्रतिलिपि बनाने के लिए 'const' * * आवश्यक नहीं है। –

+0

@ कोनराड रुडॉल्फ यह गलत लगता है क्योंकि यह गलत था, मेरी सोच टोपी पीछे की ओर थी। –

2

क्यों में पैरामीटर करता है करने के लिए मूल्यांकन करेगा स्ट्रिंगटेस्ट को जब कॉन्स्ट चिह्नित किया जाना चाहिए एक सी-शैली स्ट्रिंग पारित किया?

संपादित करें: टेम्पोरर्स अपरिवर्तनीय होना चाहिए। लार्सन टिप्पणी और उत्तर देखें, वह सही है।

सरल कारण:

void change(std::string& c) { c = "abc"; } 
change("test"); // what should the code exactly do?? 

इसके अलावा, क्या होगा एक cstyle स्ट्रिंग निर्माता देखो की तरह, और कैसे संकलक देखकर यह आह्वान करने के लिए पता है:

यह std::string के लिए लग रहा है string(char*) कन्स्ट्रक्टर

कुछ के मामले में जैसे ing:

std::string s = "HelloWorld"; 

cstyle एक अस्थायी std :: स्ट्रिंग, और फिर अस्थायी स्ट्रिंग "एस" स्ट्रिंग प्रतिलिपि निर्माता का उपयोग कर ?: std :: स्ट्रिंग में बनाई जाए दृष्टांत के लिए इस्तेमाल किया निर्माता (स्थिरांक एसटीडी है :: स्ट्रिंग &);

नहीं। इस सटीक मामले (TYPE variable = SOMETHING) में, यह TYPE variable(SOMETHING); लिखने जैसा ही है। तो, कोई प्रतिलिपि का उपयोग नहीं किया जाता है।

+0

आपका पहला और तीसरा अंक गलत है। –

+0

@ कोनराड, क्या आप वाकई तीसरे बिंदु गलत हैं? – nothrow

+0

हां ... लार्सन का जवाब देखें (लेकिन इसके नीचे भी मेरी टिप्पणी)। –

2

क्या यह आसानी से char * की तरह कुछ स्ट्रिंग अक्षर को पहचानता है?

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

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

int main(void) 
{ 
    cout << "Hello!" << endl; 
    return 0; 
} 

यह क्या के करीब है "वास्तव में" हो रहा:

const char HELLO_STR[] = { 'H', 'e', 'l', 'l', 'o', '!', 0 }; 

int main(void) 
{ 
    cout << HELLO_STR << endl; 
    return 0; 
} 

मुझे माफ कर दो, तो मैंने सरणी init या जो कुछ भी में एक त्रुटि की, लेकिन मुझे लगता है कि यह अभिव्यक्त करता है कि मेरा मतलब क्या है जहां स्ट्रिंग अक्षर "वास्तव में" संग्रहीत है। यह ऑनलाइन नहीं है, लेकिन कार्यक्रम के दूसरे भाग में एक अदृश्य स्थिर है जहां इसे परिभाषित किया गया है। इसके अलावा, वहां कुछ (अधिकांश?) कंपाइलर्स स्ट्रिंग अक्षर "एक साथ" व्यवस्थित करते हैं ताकि यदि आपके पास 50 स्थानों में समान शाब्दिक उपयोग किया गया हो, तो यह केवल उनमें से एक को स्टोर करता है, और उनमें से सभी एक ही स्थिरांक को संदर्भित करते हैं, स्मृति की बचत

तो याद रखें कि जब भी आप एक स्ट्रिंग अक्षर का उपयोग कर रहे हैं, तो आप एक कॉन्स char [N] का उपयोग कर रहे हैं जो कहीं भी "अदृश्य" मौजूद है, जो निश्चित रूप से कॉन्स्ट char * में परिवर्तित हो गया है।