2012-06-12 12 views
15

जब मैं किसी प्रक्रिया में const पैरामीटर का उपयोग करता हूं तो इससे क्या फर्क पड़ता है? और केवल पढ़ने के लिए - पैरामीटर Text: String (मैं जानता हूँ कि जहाँ तक) तो const कि उपसर्ग के साथ किया जाता है, मूल्य की एक प्रतिलिपि बना और प्रयोग किया जाता हैजब मैं प्रक्रिया के पैरामीटर में "const" का उपयोग करता हूं तो इससे क्या अंतर होता है?

procedure DoSomething(Sender: TObject; const Text: String; var Reply: String); 
begin 
    //Text is read-only and Reply will be passed back wherever DoSomething() was called 
    Reply:= Text; 
end; 

:

उदाहरण के लिए निम्नलिखित प्रक्रिया ले लो । मैं क्या सोच रहा था यह है कि अगर मैं const नहीं डालता तो इससे अलग-अलग एप्लिकेशन को कैसे प्रभावित किया जाता है? शायद एक प्रदर्शन चाल?

+1

यहाँ उत्तर दिया? http://stackoverflow.com/a/1601124/496736 –

+2

ज्यादातर मामलों में, मुझे लगता है कि सभी इनपुट-केवल पैरामीटर को 'कॉन्स्ट' के रूप में चिह्नित करने का मुख्य लाभ यह है कि आप प्रोग्रामर को मूर्खता से बचने में अतिरिक्त सहायता मिलेगी कीड़े। –

+1

@ एंड्रियास क्या गड़बड़ है कि 'कॉन्स्ट' को इंटरफ़ेस और कार्यान्वयन दोनों में शामिल करने की आवश्यकता है। यह एक ऐसा क्षेत्र है जहां सी ++ डेल्फी धड़कता है। –

उत्तर

22

documentation राज्यों को देखते हुए:

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

उदाहरण के लिए स्ट्रिंग के मामले में ऑप्टिमाइज़ेशन का मतलब है कि कॉन्स्ट के रूप में पास होने पर कोई अतिरिक्त रेफउंटिंग नहीं होती है। का मतलब यह नहीं है कि यह एक प्रतिलिपि है। अक्सर यह आंतरिक रूप से संदर्भ के रूप में गुजरता है क्योंकि संकलक इसे कोई लेखन पहुंच सुनिश्चित नहीं करता है।

कुछ बहुत ही दिलचस्प लेख को पूरी तरह से समझने के लिए क्या हुड के नीचे हो रहा है:

http://delphitools.info/2010/07/28/all-hail-the-const-parameters

http://vcldeveloper.com/articles/different-function-parameter-modifiers-in-delphi

संपादित करें:

कि स्थिरांक द्वारा पास में हो सकता है दिखाने के लिए एक सरल उदाहरण आंतरिक रूप से संदर्भ:

program Project1; 

{$APPTYPE CONSOLE} 

type 
    PMyRecord = ^TMyRecord; 
    TMyRecord = record 
    Value1: Cardinal; 
    Value2: Cardinal; 
    end; 

procedure PassAsConst(const r: TMyRecord); 
begin 
    PMyRecord(@r).Value1 := 3333; 
    PMyRecord(@r).Value2 := 4444; 
end; 

procedure PassByVal(r: TMyRecord); 
begin 
    PMyRecord(@r).Value1 := 3333; 
    PMyRecord(@r).Value2 := 4444; 
end; 

var 
    r: TMyRecord; 
begin 
    r.Value1 := 1111; 
    r.Value2 := 2222; 
    PassByVal(r); 
    Writeln(r.Value1); 
    Writeln(r.Value2); 

    PassAsConst(r); 
    Writeln(r.Value1); 
    Writeln(r.Value2); 

    Readln; 
end. 
+3

FWIW: यह कैसे ** ** ** पास किया गया है, इससे कोई फर्क नहीं पड़ता कि पैरामीटर स्थिर है या नहीं। यदि इसे स्पष्ट रूप से 'var' या 'out' घोषित नहीं किया गया है, तो यह ** ** ** ** को कॉन्स या गैर-कॉन्स के लिए समान होगा। आम तौर पर, पंजीकरण आकार (कहें, 32 बिट) से बड़ा आइटम ** संदर्भ द्वारा ** पास किया जाएगा, इससे कोई फर्क नहीं पड़ता कि वे हैं या नहीं। कॉन्स और गैर-कॉन्स के बीच एकमात्र अंतर यह है कि गैर-कॉन्स के लिए, छिपे हुए कोड को प्रारंभ में डाला जाता है जो आइटम को स्थानीय संग्रहण में कॉपी करता है। कॉन्स के लिए, केवल पढ़ने के संदर्भों की अनुमति है, इसलिए यह प्रतिलिपि कोड गुम है और पास संदर्भ सीधे उपयोग किया जाता है। –

6

जब आपके पास कॉन्स उपसर्ग नहीं है, तो संकलक को यह मानना ​​होगा कि आप पैरामीटर बदल रहे हैं। इसका मतलब यह है कि इसे कॉपी करना और एक छिपी कोशिश स्थापित करना ... आखिर में स्थानीय स्ट्रिंग वैरिएबल का निपटान करने के लिए, इसलिए कभी-कभी कॉन्स एक महत्वपूर्ण प्रदर्शन सुधार प्राप्त कर सकता है। यह जेनरेट कोड को छोटा बनाता है।

+0

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

+0

यह डेल्फी के सभी संस्करणों में सच है जो कॉन्स्ट पैरामीटर को जानते हैं, यानी डी 2007 से पहले: संरचनाओं की प्रतिलिपि बनाने की कोई आवश्यकता नहीं है, अगर वे संदर्भ द्वारा पारित किए गए थे (यह उनके आकार पर निर्भर करता है), स्थानीय भंडारण में और संदर्भ गणना करने की आवश्यकता नहीं है। –

1

एक कॉन्स का उपयोग करते समय दक्षता के पिछले उत्तरों के अलावा (यानी। कंपाइलर को चर की प्रतिलिपि बनाने की आवश्यकता नहीं है), यदि आप एक इंटरफ़ेस पैरामीटर के साथ एक कॉन्स का उपयोग करते हैं, तो यह रेफ गिनती के ट्रिगरिंग को रोकता है।

+0

इस व्यवहार का कारण कौन सा है: http://qc.embarcadero.com/wc/qcmain.aspx?d=75036 –

+3

संदर्भ-गणना की कमी इंटरफेस और तारों के लिए समान है। इंटरफेस के बारे में आपने जो कहा है वह तारों के बारे में सामान के अलावा "नहीं है"। * परिवर्तनीय * हर समय कॉपी हो जाता है, लेकिन उनको कॉपी करना सस्ता है क्योंकि यह सिर्फ एक सूचक के मूल्य की प्रतिलिपि बना रहा है, जो कि कभी-कभी किसी मान फ़ॉर्म को कॉपी करने से अधिक नहीं होता है। –

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

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