2012-04-27 9 views
9

मैंने इसे गुगल किया है और कई पोस्ट पढ़ी हैं, लेकिन इतने सारे अलग-अलग उत्तर हैं कि सभी तार्किक अर्थ बनाते हैं कि मैं सोच रहा था कि विषय पर कोई विशेषज्ञ इस प्रश्न को नष्ट कर सकता है या नहीं।सी ++ रचनाकारों के पास कोई वापसी प्रकार नहीं है। बस क्यों?

कुछ कहते हैं कि वापसी नहीं करने के लिए कोई रास्ता नहीं है - वाक्यविन्यास इसे प्रतिबंधित करता है - हाँ, यह समझ में आता है, लेकिन मेरा मानना ​​है कि सभी कार्यों को कुछ वापस करना है, नहीं? अन्य कहते हैं कि कन्स्ट्रक्टर प्रकार नए बनाए गए ऑब्जेक्ट को वापस लौटाता है, जो कि समझ में आता है क्योंकि असाइनमेंट ऑपरेटर को कन्स्ट्रक्टर पर उपयोग किया जाता है। फिर भी दूसरों के पास अन्य दिलचस्प स्पष्टीकरण हैं।

+0

जिज्ञासा से बाहर, जब यह समझ बनाने के निर्माता लौट वस्तु यह निर्माण कर रही है के अलावा और कुछ है करने के लिए उपयोगी हो सकता है या यहाँ तक कि होगा? – kevin628

+0

AFAIK यह नव निर्मित ऑब्जेक्ट देता है। –

+4

कौन कहता है कि एक कन्स्ट्रक्टर एक समारोह है? (इस तथ्य के अलावा कि "विशेष सदस्य कार्य" पर मानक अनुभाग में वर्णित है) –

उत्तर

12

रचनाकारों को अन्य कार्यों की तरह नहीं कहा जाता है, इसलिए वे अन्य कार्यों की तरह वापस नहीं आते हैं। वे कुछ संरचनाओं (कास्ट, new, परिवर्तनीय परिभाषा, सीटीओआर-प्रारंभकर्ता-सूची, पास-दर-मूल्य, वापसी-दर-मूल्य) के दुष्प्रभाव के रूप में निष्पादित करते हैं।

8

कन्स्ट्रक्टर इन-प्लेस बनाता है, इसे कुछ भी वापस करने की आवश्यकता नहीं है।

मेरा मानना ​​है कि सभी कार्यों कुछ

void वापस जाने के लिए है?

+0

रचनाकार 'शून्य' वापस नहीं लौटाते हैं (अगर यह समझ में आता है)।उनके पास कोई रिटर्न प्रकार नहीं है। –

+1

@ डेविडहैमेन यह वाक्यविन्यास में केवल एक अंतर है। फ़ंक्शन के रिटर्न प्रकार को 'शून्य' होने के लिए घोषित करना एक ही अर्थ है। – bames53

+0

क्या यह वाक्यविन्यास में केवल एक अंतर है? एक कन्स्ट्रक्टर इस अर्थ में एक शून्य कार्य है कि एक कन्स्ट्रक्टर में रिटर्न स्टेटमेंट 'रिटर्न' होना चाहिए। हालांकि, कन्स्ट्रक्टर को अचूक बनाकर और रिटर्न प्रकार को निर्दिष्ट करके छोड़कर, मानक एक कंपाइलर विक्रेता को ऐसा करने के लिए अनुमति देता है जब तक कि यह कार्य करता है-जैसे यह शून्य हो रहा है। –

1

कि रचनाकारों में रिटर्न प्रकार की कमी है - यहां तक ​​कि void भी नहीं - इसका मतलब है कि आप अपने सी ++ कोड से कन्स्ट्रक्टर को कॉल नहीं कर सकते हैं। और वह बात है। एक कन्स्ट्रक्टर को कॉल करना समझ में नहीं आता है। एक कन्स्ट्रक्टर को कॉल करने के लिए इसे अवैध बनाना इस प्रकार की उपयोगकर्ता त्रुटि की संभावना को समाप्त करता है।

संपादित

बार्न्स सही है कि में है परम कारण आप कंस्ट्रक्टर्स कॉल नहीं कर सकते वे कोई नाम नहीं होता है। (और यहां तक ​​कि इस पर ध्यान नहीं देता है कि आप प्लेसमेंट नई के माध्यम से परोक्ष रूप से एक निर्माता कॉल कर सकते हैं।)

फिर से कोशिश कर रहा है:

आप अपने सी से कंस्ट्रक्टर्स कॉल नहीं कर सकते ++ कोड क्योंकि कंस्ट्रक्टर्स एक नाम नहीं है। रचनाकारों को रिटर्न टाइप नहीं करना प्रोग्रामर पर जोर देता है कि रचनाकार अन्य कार्यों की तुलना में एक बहुत ही अलग प्रकार के फ़ंक्शन हैं। वास्तव में कोई कन्स्ट्रक्टर वापस लौटाता है, अगर यह कुछ भी लौटाता है, तो विक्रेता तक है।

+0

तथ्य यह है कि कन्स्ट्रक्टर कुछ भी वापस नहीं लौटाता है, इसके साथ कुछ भी नहीं है कि आप एक कन्स्ट्रक्टर को कॉल कर सकते हैं या नहीं। आप एक कन्स्ट्रक्टर को कॉल नहीं कर सकते क्योंकि रचनाकारों का नाम नहीं है, और इसे कॉल करने के लिए कोई वाक्यविन्यास नहीं है। (केवल एक कामकाज; नया प्लेसमेंट)। – bames53

10

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

+2

और जो चीज * दिखता है * एक कन्स्ट्रक्टर कॉल की तरह वास्तव में एक कलाकार है। –

+2

@downvoter कृपया अपने वोट – dasblinkenlight

1

लेकिन मेरा मानना ​​है कि सभी कार्यों को कुछ वापस करना है, नहीं?

नहीं। फ़ंक्शन से मूल्य वापस करने का क्या अर्थ है? खैर, एबीआई एक कार्यान्वयन के लिए निर्दिष्ट करेगा कि कुछ रिटर्न प्रकार के लिए एक फ़ंक्शन कुछ रजिस्टरों, या स्टैक पॉइंटर से कुछ ऑफ़सेट पर कुछ मेमोरी सेट करेगा, जो फ़ंक्शन द्वारा 'लौटाया गया' मान होगा।

जाहिर पंजीकृत करता है और स्मृति मौजूद हैं और कहा जाता है एक निर्माता या शून्य समारोह के बाद डेटा होते हैं, लेकिन भाषा कहते हैं उन कार्यों कुछ भी वापस नहीं है, और इसलिए ABI जो पंजीकृत करता है या स्मृति में देखने के लिए पता लगाने के लिए निर्दिष्ट नहीं करता एक वापसी मूल्य। कोड रिटर्न वैल्यू सेट नहीं कर सकता है और कॉलिंग कोड को कोई रिटर्न वैल्यू मिल सकता है।

तो नहीं, कार्यों को कुछ भी वापस करने की आवश्यकता नहीं है।

class Object{ 
    public: 
     bool Object(){ ... }; 
     ... 
}  

SomeFun(Object obj){ ... } 

SomeFun(Object()); 
// Ha! SomeFun jokes on an error about a non-Object argument(of type bool), returned 
// by the anonymous temporary Object() 

लौटने से निर्माता कार्यों की रोकथाम,, अनाम temporaries के उपयोग की सुविधा कई और अधिक सी ++ सुविधाओं के साथ:

2

मानते हुए कंस्ट्रक्टर्स कुछ लौटा सकता है, तो यह निम्नलिखित समारोह कॉल के लिए समस्या पैदा करने वाले प्रभाव पड़ता है। इस तरह के एक नियम के बिना, अहानिकर बयान अस्पष्ट हो सकता है:

Object obj(Object()); 
// How does the variable obj decide which constructor to call, 
// based on its argument type? 
// 
// Does it call: bool Object::Object(Object&) or 
//     Object::Object(bool)(if it exists)? 

निर्माताओं के लिए क्षमता एक मूल्य के वापस जाने के लिए, ऑब्जेक्ट के निर्माण के पेचीदा हो -, एक भी स्पष्ट प्रकार, वर्ग के नाम होने मनमाने ढंग से वापसी मान के अभाव में , ऐसी समस्याओं से बचाता है।

क्या पाठक ऐसे उदाहरण सुझा सकते हैं जहां सी ++ मुहावरे इस तरह के नियम की अनुपस्थिति से बाधित हैं?

+0

को समझाएं, यह तर्क हमें विश्वास करेगा कि एक रचनाकार जो मनमानी मूल्यों को वापस कर रहा है वांछनीय होगा अगर यह अन्य स्थापित भाषा सुविधाओं को गलत तरीके से रगड़ न दे ... इसके विपरीत, एक कन्स्ट्रक्टर विशेष उद्देश्य कार्य है [उपयोग किया जाता है अपनी कक्षा की वस्तुओं को आरंभ करने के लिए] (http://www2.research.att.com/~bs/glossary.html#Gconstructor) ... उस प्रकाश में अपना जवाब दोबारा दोहराएं ... – user1055604

0

रचनाकार पूरी तरह कक्षा के एक उदाहरण को वापस लौटते हैं। यह विरोधाभासी होगा यदि इसे कुछ वापस करने के लिए डिज़ाइन किया गया था और प्रोग्रामर ने कक्षा के अलावा कुछ अलग-अलग कुछ भी वापस कर दिया था। मूल रूप से वाक्यविन्यास उलझन में होगा।

1

रचनाकार शायद इसके लिए एक बुरा नाम हैं। यह व्यावहारिक रूप से पूर्व निर्मित वस्तुओं के लिए एक प्रारंभिक है। इसे चित्रित करने का सबसे आसान तरीका सी ++ रचनाकारों का उपयोग किये बिना समकक्ष निर्माण के लिए एक छद्म उदाहरण है।

कंस्ट्रक्टर्स

struct X { 
    int a; 
    X() { 
     a = -5; 
    } 
}; 

int main() { 
    X* x1 = new X(); // X created as a "reference object". 
    X x2;   // X created as a "value object" on the stack. 
    return x1->a - x2.a; 
} 

साथ

कंस्ट्रक्टर्स बिना

struct X { 
    int a; 
    void initialize() { 
     a = -5; 
    } 
    static X* create() { 
     X* res = (X*)malloc(sizeof(X)); 
     res->initialize(); 
     return res; 
    } 
}; 

int main() { 
    X* x1 = X::create(); // New constructed heap-allocated X 
    X x2;    // Stack-allocated X 
    x2.initialize();  // Manually initialized 
    return x1->a - x2.a; 
} 

अब, अगर आप कल्पना कर दूसरे उदाहरण में X::initialize थे कि वापस जाने के लिए किए जाने के लिए कहते हैं, एक bool सफलता या विफलता का संकेत है, क्या तुम करोगी समस्या होना। main() में, अवांछित प्रोग्रामर X के साथ समाप्त हो सकता है जिसे ठीक तरह से प्रारंभ नहीं किया गया है, जो अनिर्धारित व्यवहार (आमतौर पर हार्ड-डीबग क्रैश जो उत्पादन से पहले नहीं खोजा जा सकता है) का कारण बनता है।

यह मुख्य कारणों में से एक है कि क्यों रचनाकारों को विशेष बनाया जाता है। एक कन्स्ट्रक्टर से बाहर निकलने के लिए केवल दो तरीके सामान्य समापन के माध्यम से या अपवाद के माध्यम से होते हैं, जो होना चाहिए, फिर कॉलर (या स्टैक पर पारित) द्वारा संभाला जाना चाहिए। किसी भी मामले में, आप अनियमित वस्तुओं के साथ समाप्त होने से रोकते हैं।

अतिरिक्त नोट के रूप में, अप्रारंभीकृत वस्तुओं सी में कीड़े की अधिक सामान्य कारणों, जो इस तरह प्रोग्रामर मदद करने के लिए कुछ भी नहीं है में से एक हैं।

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