मैं स्वयं के बारे में अपनी समझ को आगे बढ़ाने के लिए कह रहा हूं।

कृपया निम्नलिखित पर विचार करें:

type
  PTestObject = ^TTestObject;
  TTestObject = class(TObject)
  private
    FCaption : String;
  public
    procedure MakeThePointer;

    property Caption : String read FCaption write FCaption;
  end;

  TForm4 = class(TForm)
    ButtonFirst: TButton;
    ButtonSecond: TButton;
    ButtonThird: TButton;
    procedure ButtonFirstClick(Sender: TObject);
    procedure ButtonSecondClick(Sender: TObject);
    procedure ButtonThirdClick(Sender: TObject);
  private
  public
  end;

var
  Form4: TForm4;
  PointerOfTest : PTestObject;
  TestObj : TTestObject;

implementation

{$R *.dfm}

procedure TTestObject.MakeThePointer;
begin
  PointerOfTest := @Self;
end;

procedure TForm4.ButtonFirstClick(Sender: TObject);
begin
  TestObj := TTestObject.Create;
  TestObj.Caption := 'Hello';
  TestObj.MakeThePointer;
end;

procedure TForm4.ButtonSecondClick(Sender: TObject);
begin
  TestObj.MakeThePointer;
  ShowMessage(PointerOfTest^.Caption);
end;

procedure TForm4.ButtonThirdClick(Sender: TObject);
begin
  // TestObj.MakeThePointer; - Because I do not do this I get Access Violation
  ShowMessage(PointerOfTest^.Caption);
end;

विचार यह है कि TestObj's Self के लिए एक पॉइंटर बनाया जाए और बाद में इसे फिर से एक्सेस किया जाए। अगर मैं उसी क्लिक इवेंट (ButtonSecondClick) में MakeThePointer को कॉल करता हूं, जहां मैं उस पॉइंटर तक पहुंचता हूं तो यह ठीक काम करता है। अगर मैं पॉइंटर (ButtonThirdClick) तक पहुंचने से पहले MakeThePointer को कॉल नहीं करता तो ऐसा लगता है कि TestObj's Self इस तरह से मौजूद नहीं है कि पहले बनाया गया पॉइंटर मान्य है और मुझे एक्सेस उल्लंघन मिलता है .

अगर मैं गलत हूं तो कृपया मुझे सुधारें लेकिन मुझे लगता है कि स्वयं प्रत्येक वस्तु के तरीकों के लिए एक परिवर्तनीय स्थानीय है। इस प्रकार यह केवल उन तरीकों में से प्रत्येक के लिए अलग से गुंजाइश होगी?

अब इस पर विचार करें... यदि ऐसा है तो निम्न कार्य क्यों करता है यदि ButtonFirst क्लिक किया जाता है, तो ButtonSecond? ऐसा लगता है कि सेल्फ वेरिएबल एक ही पते पर आ गया है जिससे निम्नलिखित को काम करने की इजाजत मिलती है। क्या मैं यह मान सकता हूँ कि Self चर हमेशा एक ही पते पर रहेगा या यह बदलेगा?

type
  TFormOther = class(TForm)
    ButtonFirst: TButton;
    ButtonSecond: TButton;
    procedure ButtonFirstClick(Sender: TObject);
    procedure ButtonSecondClick(Sender: TObject);
  private
  public
    procedure MakeThePointer;
    procedure SetTheCaption;
  end;

var
  FormOther: TFormOther;
  PointerOfForm : ^TForm;

implementation

{$R *.dfm}

procedure TFormOther.MakeThePointer;
begin
  PointerOfForm := @Self;
end;

procedure TFormOther.SetTheCaption;
begin
  PointerOfForm^.Caption := 'Hello';
end;

procedure TFormOther.ButtonFirstClick(Sender: TObject);
begin
  MakeThePointer;
end;

procedure TFormOther.ButtonSecondClick(Sender: TObject);
begin
  SetTheCaption;
end;
5
Blurry Sterk 7 फरवरी 2017, 11:53

1 उत्तर

सबसे बढ़िया उत्तर

स्वयं का दायरा क्या है?

एक विधि में Self को स्थानीय चर के रूप में सबसे अच्छा माना जाता है। इसलिए इसका पता, @Self, विधि के वापस आने तक मान्य है।

यह बताता है कि आपका कोड क्यों विफल रहता है। आपका कोड विधि के वापस आने के बाद पॉइंटर को डीरेफरेंस करता है, जिस बिंदु तक पॉइंटर मान्य नहीं है।

क्या मैं मान सकता हूं कि स्वयं चर हमेशा एक ही पते पर रहेगा?

नहीं, तुम नहीं कर सकते हो।


मुझे लगता है कि आपकी समस्याएं यहां से शुरू होती हैं:

type
  PTestObject = ^TTestObject;

क्योंकि TTestObject एक वर्ग है, एक प्रकार का चर TTestObject, जैसे कि आपका Self, एक संदर्भ है। एक संदर्भ एक सूचक के लिए एक फैंसी नाम है। इस मामले में, आपका Self, TTestObject के अंदर के तरीके उदाहरण के लिए एक सूचक है।

इसलिए ^TTestObject के बजाय TTestObject का उपयोग करें और आपकी समस्याएं दूर हो जाएंगी।

4
David Heffernan 7 फरवरी 2017, 12:16