2008-09-08 15 views
21

मैंने एक परियोजना से दूसरे प्रोजेक्ट में कुछ डेल्फी कोड की प्रतिलिपि बनाई, और पाया कि यह नई परियोजना में संकलित नहीं है, हालांकि यह पुराने में किया गया था। कोड इस तरह दिखता है:डेल्फी 7 में, मैं एक कॉन्स को मूल्य क्यों निर्दिष्ट कर सकता हूं?

procedure TForm1.CalculateGP(..) 
const 
    Price : money = 0; 
begin 
    ... 
    Price := 1.0; 
    ... 
end; 

तो नई परियोजना में, डेल्फी शिकायत है कि "बाईं ओर करने के लिए आवंटित नहीं किया जा सकता" - समझ में आता है! लेकिन यह कोड पुरानी परियोजना में संकलित है। तो मेरा सवाल है, क्यों? क्या कॉन्स्टाइल को पुन: असाइन करने की अनुमति देने के लिए कोई कंपाइलर स्विच है? इससे काम होता ही कैसे है? मैंने सोचा कि संकलन समय पर कॉन्स को उनके मूल्यों से बदल दिया गया था?

उत्तर

29

आपको असाइन करने योग्य टाइप किए गए स्थिरांक चालू करने की आवश्यकता है। परियोजना -> विकल्प -> संकलक -> आबंटित स्थिरांक

टाइप किया इसके अलावा, आप क़दम फ़ाइल है, जो शायद बेहतर है के लिए {$J+} या {$WRITEABLECONST ON} जोड़ सकते हैं, क्योंकि यह काम करेंगे, भले ही आप एक अन्य परियोजना में फ़ाइल।

+2

यह चाल है। Google कंपाइलर निर्देश {$ J +} होने का खुलासा करता है। यह प्रोजेक्ट विकल्पों में भी है, शायद वहां देखा जाना चाहिए था: पी – Blorgbeard

+0

हाँ मैं इससे पहले मारा गया था। (मेरी प्रारंभिक पोस्ट के बाद विवरण जोड़ने के लिए संपादित) – Ray

+1

आईएमएचओ '{$ WRITABLECONST OFF}' 'J +}' से भी betterer होगा। –

27

टाइप-inferred स्थिरांक केवल अदिश मूल्यों हो सकता है - पूर्णांकों की तरह अर्थात बातें, युगल, आदि स्थिरांक की इन प्रकार के लिए, संकलक वास्तव में निरंतर के मूल्य जब भी यह उन्हें भाव में मिलता है के साथ लगातार की प्रतीक की जगह है।

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

यह समझाने के लिए कि ऐतिहासिक रूप से, प्रारंभिक डेल्फी और उसके पूर्ववर्ती टर्बो पास्कल में टाइप किए गए स्थिरांक क्यों लिखते हैं (और इस प्रकार अनिवार्य रूप से वैश्विक चर शुरू किए जाते हैं), हमें डॉस के दिनों में वापस जाना होगा।

डॉस वास्तविक मोड में x86 शब्दों में चलता है। इसका अर्थ यह है कि प्रोग्राम्स के पास वर्चुअल-भौतिक मैपिंग करने वाले MMU बिना भौतिक मेमोरी तक सीधे पहुंच है। जब प्रोग्राम में स्मृति तक सीधे पहुंच होती है, तो कोई स्मृति सुरक्षा प्रभावी नहीं होती है। दूसरे शब्दों में, यदि किसी दिए गए पते पर स्मृति है, तो यह रीयल-मोड में पठनीय और लिखने योग्य दोनों है।

तो, टाइप किए गए निरंतर वाले डॉस के लिए टर्बो पास्कल प्रोग्राम में, जिसका मान रनटाइम पर स्मृति में किसी पते पर आवंटित किया जाता है, जो टाइप किया गया निरंतर लिखने योग्य होगा। रास्ते में कोई हार्डवेयर एमएमयू नहीं हो रहा है और प्रोग्राम को इसे लिखने से रोक रहा है। इसी तरह, क्योंकि पास्कल के पास 'कॉन्स्टनेस' की कोई धारणा नहीं है, सी ++ में, आपको रोकने के लिए टाइप सिस्टम में कुछ भी नहीं है। बहुत से लोगों ने इसका लाभ उठाया, क्योंकि उस समय टर्बो पास्कल और डेल्फी ने उस समय के रूप में वैश्विक चर को शुरू नहीं किया था। स्मृति प्रबंधन इकाई:

Windows के लिए आगे बढ़ते, वहाँ स्मृति पते और भौतिक पते के बीच एक परत है। यह चिप उस मेमोरी पते का पेज इंडेक्स (एक स्थानांतरित मुखौटा) लेता है जिसे आप एक्सेस करने का प्रयास कर रहे हैं, और इस पृष्ठ के गुणों को page table में देखता है। इन विशेषताओं में पठनीय, लिखने योग्य, और आधुनिक x86 चिप्स, गैर निष्पादन योग्य झंडे शामिल हैं। इस समर्थन के साथ, .EXE या .DLL के अनुभागों को गुणों के साथ चिह्नित करना संभव है जैसे कि जब Windows लोडर निष्पादन योग्य छवि को स्मृति में लोड करता है, तो यह स्मृति पृष्ठों के लिए उचित पृष्ठ विशेषताओं को निर्दिष्ट करता है जो इन वर्गों के भीतर डिस्क पृष्ठों पर मैप करते हैं।

जब डेल्फी संकलक के 32-बिट Windows संस्करण के आसपास आ गया, यह इस प्रकार भावना स्थिरांक-तरह बातें वास्तव में स्थिरांक बनाने के लिए, बना के रूप में ओएस भी इस सुविधा है।

+0

@ बैरी द्वारा उल्लिखित नहीं है, क्या आपके पास असाइन करने योग्य स्थिरांक का उपयोग करने के लिए * क्यों * निराश हो गया है? मैं वास्तव में इस तथ्य की तरह हूं कि स्थानीय लेखन योग्य स्थिरांक वैश्विक चर की तरह व्यवहार करते हैं लेकिन केवल स्थानीय दायरे में ही दिखाई देते हैं। –

+0

@LievenKeersmaekers क्योंकि स्थिरांक स्थिर होना चाहिए। –

+0

@ बररीकेली - लॉल, यह मेरा मुद्दा नहीं था। उनको नाम दें जो आपके लिए काम करते हैं :)। मुझे * कार्यक्षमता * प्रदान करना पसंद है। टाइप किए गए स्थिरांक के सभी विकल्प तब कम कंसिस होते हैं, ठीक है, टाइप किए गए स्थिरांक। –

11
  1. क्यों: क्योंकि डेल्फी के पिछले संस्करणों में टाइप स्थिरांक डिफ़ॉल्ट रूप से आबंटित पुराने संस्करणों जहां वे हमेशा लिखने योग्य थे (डेल्फी 1 जल्दी पास्कल करने के लिए) के साथ संगतता बनाए रखने के लिए कर रहे थे।
    डिफ़ॉल्ट अब स्थिरांक वास्तव में निरंतर बनाने के लिए बदल दिया गया है ...

  2. संकलक स्विच: {$ जे +} या {$ जम्मू} {$ WRITEABLECONST पर} या {$ WRITEABLECONST बंद}
    या में इस परियोजना के लिए विकल्पों कंपाइलर के लिए: असाइन करने योग्य टाइप किए गए कॉन्स्टेंट्स की जांच करें

  3. यह कैसे काम करता है: यदि कंपाइलर संकलन समय पर मान की गणना कर सकता है, तो यह कोड में हर जगह इसके मूल्य से प्रतिस्थापन को प्रतिस्थापित करता है, अन्यथा यह स्मृति क्षेत्र में एक सूचक होता है मूल्य, जिसे लिखने योग्य या नहीं बनाया जा सकता है।
  4. 3.
2

देखने जैसा बैरी ने कहा, लोगों consts का फायदा उठाया; इसका उपयोग करने के तरीकों में से एक, सिंगलटन के उदाहरणों को ट्रैक रखने के लिए था। यदि आप क्लासिक सिंगलटन कार्यान्वयन को देखते हैं, तो आप इसे देखेंगे:

// Example implementation of the Singleton pattern. 
    TSingleton = class(TObject) 
    protected 
    constructor CreateInstance; virtual; 
    class function AccessInstance(Request: Integer): TSingleton; 
    public 
    constructor Create; virtual; 
    destructor Destroy; override; 
    class function Instance: TSingleton; 
    class procedure ReleaseInstance; 
    end; 

constructor TSingleton.Create; 
begin 
    inherited Create; 

    raise Exception.CreateFmt('Access class %s through Instance only', [ClassName]); 
end; 

constructor TSingleton.CreateInstance; 
begin 
    inherited Create; 

    // Do whatever you would normally place in Create, here. 
end; 

destructor TSingleton.Destroy; 
begin 
    // Do normal destruction here 

    if AccessInstance(0) = Self then 
    AccessInstance(2); 

    inherited Destroy; 
end; 

{$WRITEABLECONST ON} 
class function TSingleton.AccessInstance(Request: Integer): TSingleton; 
const 
    FInstance: TSingleton = nil; 
begin 
    case Request of 
    0 : ; 
    1 : if not Assigned(FInstance) then 
      FInstance := CreateInstance; 
    2 : FInstance := nil; 
    else 
    raise Exception.CreateFmt('Illegal request %d in AccessInstance', [Request]); 
    end; 
    Result := FInstance; 
end; 
{$IFNDEF WRITEABLECONST_ON} 
    {$WRITEABLECONST OFF} 
{$ENDIF} 

class function TSingleton.Instance: TSingleton; 
begin 
    Result := AccessInstance(1); 
end; 

class procedure TSingleton.ReleaseInstance; 
begin 
    AccessInstance(0).Free; 
end;