2011-07-04 12 views
5
TMyClass = class(TObject) 
private 
    FMyObject: TObject; 
    function GetMyObject: TObject; 
public 
    property MyObject: TObject read GetMyObject write FMyObject; 
end; 

function TMyClass.GetMyObject: TObject; 
begin 
    if FMyObject = nil then 
    FMyObject := TObject.Create; 

    Result := FMyObject; 
end; 

कभी-कभी, "मायऑब्जेक्ट" आंतरिक रूप से नहीं बनाया जाता है लेकिन बाहरी रूप से बनाया गया है और पैरामीटर को असाइन किया गया है। यदि यह ऑब्जेक्ट बाहरी रूप से बनाया गया है, तो मैं इसे इस संदर्भ में मुक्त नहीं कर सकता।ऑब्जेक्ट-फ़ील्ड प्रकार जीवन-चक्र को नियंत्रित करने का सबसे अच्छा तरीका कौन सा है?

क्या मुझे एक टीएलिस्ट बनाना चाहिए और उन सभी वस्तुओं में जोड़ें जो आंतरिक रूप से बनाए गए थे और विनाशक पर सब कुछ नष्ट कर चुके थे?

अगर मैं आंतरिक रूप से बनाया गया है या नहीं तो पैरामीटर के जीवनकाल को मैं कैसे नियंत्रित कर सकता हूं? आप क्या करने का सुझाव देते हैं? क्या ऐसा करने के लिए कोई पैटर्न है?

+0

यदि इसका निजी एक्सेस संशोधक है तो MyObject को बाहरी रूप से कैसे बनाया जा सकता है? इस कक्षा में कुछ भी नहीं है इस संपत्ति को – heximal

+1

@heximal देखता है: कन्स्ट्रक्टर इंजेक्शन द्वारा सबसे अधिक संभावना (उदाहरण कोड में नहीं)। – jpfollenius

+1

@heximal: क्षेत्र निजी है, संपत्ति सार्वजनिक है और पढ़/लिखती है, यानी इसे 'Obj.MyObject: = TSomeObject.Create;' जैसे उपयोग किया जा सकता है। – ain

उत्तर

3

मुझे लगता है कि आपके कोड को फिर से डिजाइन करना सबसे अच्छा होगा ताकि यह समस्या उत्पन्न न हो - इस प्रकार की स्वामित्व अस्पष्टता एक गड़बड़ है।

वैसे भी, एक विकल्प का उपयोग करना होगा (संदर्भ गिना गया) इंटरफेस। परिपत्र संदर्भों के मामले में यह समस्याग्रस्त है।

बाहर से बनाई गई वस्तु तो केवल संदर्भ नहीं होना चाहिए अगर आप अभी भी वस्तु की आंतरिक प्रतिलिपि, जैसे

procedure TMyClass.SetMyObject(const Value: TObject); 
begin 
    MyObject.Assign(Value); 
end; 

कुछ आप आंतरिक की तुलना में अलग क्षेत्र के लिए बाहरी वस्तु आवंटित कर सकते हैं बना सकते हैं और फिर आप डॉन ' टी Free उस क्षेत्र में विनाशक। या संपत्ति सेटर में एक ध्वज सेट इतना है कि आप बाहरी वस्तु मुक्त करने के लिए नहीं पता है ...

+0

+1 वीसीएल में असाइनमेंट पैटर्न पर प्रतिलिपि का उपयोग किया जाता है, इसलिए अन्य डेल्फी डेवलपर्स से परिचित होना चाहिए, जिससे रखरखाव में वृद्धि हो। – Nat

+0

@ असाइनमेंट पर नोट कॉपी ठीक है जब तक कि आप वास्तव में किसी साझा ऑब्जेक्ट का संदर्भ नहीं लेना चाहते हैं। –

7

मैं (संपत्ति सेटर

procedure TMyClass.SetMyObject(AObject: TObject); 
begin 
    if Assigned(MyObject) and FIsMyObject then 
    FMyObject.Free; 
    FIsMyObject := False; 
    FMyObject := AObject; 
end; 

function TMyClass.GetMyObject: TObject; 
begin 
    if FMyObject = nil then 
    begin 
    FMyObject := TObject.Create; 
    FIsMyObject := True; 
    end; 

    Result := FMyObject; 
end; 

Destructor TMyClass.Destroy; 
begin 
    if FIsMyObject then 
     FMyObject.Free; 
end; 
+1

+1 मैं हमेशा इसे इस तरह से करता हूं। यह थोड़ा सा सुरुचिपूर्ण लगता है लेकिन मुझे एक विकल्प नहीं मिला है जिसे मैं पसंद करता हूं। –

1

दो सबसे तार्किक और व्यावहारिक समाधान में एक ध्वज सेट करेंगे ध्वज रखें, असाइनमेंट पर कॉपी करें) पहले से ही दिए गए हैं, लेकिन पूर्णता के लिए और चूंकि ऑब्जेक्ट फ़ील्ड को टॉब्जेक्ट प्रकार की संभावना नहीं है, यहां तीन अन्य दृष्टिकोण हैं। इनकी व्यावहारिकता ऑब्जेक्ट फ़ील्ड के प्रकार पर निर्भर करती है, भले ही आप वास्तव में अतिरिक्त बूलियन ध्वज नहीं चाहते हैं और चाहे आप इस निर्माण के लिए कुछ बुद्धिमान व्यवहार जोड़ना नापसंद करते हैं।

(चेतावनी: यह एक छोटे से दूर की कौड़ी हो सकता है।)

  • टेस्ट अगर वस्तु क्षेत्र अपने निजी ऑब्जेक्ट प्रकार की है: के स्वामित्व पर

    property MyObject: TSomeAncestor read GetMyObject write SetMyObject; 
        end; 
    
    implementation 
    
    type 
        TMyObject = class(TSomeAncestor) ... end; 
    
    destructor TMyClass.Destroy; 
    begin 
        if FMyObject is TMyObject then 
        FMyObject.Free; 
    
  • टेस्ट ऑब्जेक्ट फ़ील्ड:

    property MyObject: TOwnedObject read GetMyObject write SetMyObject; 
        end; 
    
    implementation 
    
    destructor TMyClass.Destroy; 
    begin 
        if FMyObject.Owner = Self then 
        FMyObject.Free; 
    

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

  • यदि ऑब्जेक्ट फ़ील्ड TComponent से निकलती है, तो आपको बिल्कुल भी मुक्त नहीं होना चाहिए।

+0

आह, हाँ, "मालिक परीक्षण" विकल्प का उल्लेख करना भूल गया ... – ain

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

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