Delphi Programming

  1. Home
  2. Computing & Technology
  3. Delphi Programming

Accessing an Object and its Data - Delphi OOP Part 4 / Chapter 8

Using the constructor and destructor

By Zarko Gajic, About.com

A constructor is a lot like a procedure definition. It can have parameters (ACName and AnAccNo in line 19) and can, for example, set the object’s data fields (lines 22–23).

We first saw the inherited keyword in example 2.2 step 1, where Delphi inserted it automatically as part of the VFI process. Here we see the inherited keyword followed by a method name (line 21). We use inherited here to invoke the Create method defined in the superclass. It’s the first line of the constructor, and so the constructor starts by using the inherited Create to create the object (line 21). Lines 22–23 then initialise the object’s data fields. (Delphi initialises the data fields automatically to empty strings, and we use the constructor to set different start-up values.)

A destructor also follows the standard structure for a procedure (lines 25–29). In this example we don't have any tidying up work to do, so we show a message to illustrate the principle. Whereas the call to the inherited Create is the first program statement in a constructor (line 21), the call to the inherited Destroy is usually the final statement in a destructor (line 28). Following the comments on Destroy and Free in example 4.1 step 2, we won't call Destroy directly. Instead, we'll call Free which in turn will call this destructor that we have written above (lines 25–29) if the object exists.

Ex 4.2 step 2 Using the constructor and destructor

We now modify ObjectAccessU to use this constructor (line 38 below: we’ve added two parameters). We no longer need to initialise the data fields separately (cf example 4.1 step 2 lines 39–40). So writing our own constructor both simplifies and enforces initialisation. No coding change is needed to accommodate the destructor.
26 procedure TfrmAccessObject.btnCreateClick(Sender: TObject) ;
27 begin
28   { if tests as before }
38   NewClient := TClient.Create (edtCName.Text, edtAccNo.Text) ;
39   { NewClient.SetCName (edtCName.Text) ; // no longer needed
40   NewClient.SetAccNo (edtAccNo.Text) ; }
41   { ... etc ... }
42 end;
Run and test this version of the program. Object creation operates as before, but when we free the object we first get a message before the object is destroyed. This is from the destructor we have added (step 1 line 27) and shows that Free actually does call our destructor.

If we now click the Free button a second time (without first creating an object again), the message does not appear. Why not? Clicking the Free button invokes the Free method. As we have already seen, Free tests whether the object exists. If it does, it calls the Destroy destructor and the message is displayed. If the object does not exist, ie if it has already been freed, Free does not call the destructor and so the message does not appear on the screen. To check that FreeAndNil works in the same way, replace the two separate Free and Nil statements in the user interface (example 4.1 step 2 lines 57&58) with a single FreeAndNil (NewClient) ; statement. Run the program again. If an object exists, the first click on the Free button displays the ‘destroying’ statement, but further consecutive clicks do not.

Object creation and destruction

As we have mentioned, two types of error are important to consider during object creation and destruction: memory leakage, where the reference is re-assigned before the object is freed (causing an inaccessible object), and a dangling reference, where the reference is neither set to nil nor destroyed after the object it refers to is freed.

Memory leakage

Assume we have declared a MyObjName object of class TMyClass:
var MyObjName: TMyClass;
This creates a name that acts as a reference to an object of class TMyClass. Initially, this reference is set to nil.

We now create an object and link it to the name:

MyObjName := TMyClass.Create;
When we have finished with the MyObjName, we free it and assign the reference to nil, using either:
MyObjName.Free;
MyObjName := nil;

or:

FreeAndNil (MyObjName) ;
If we do this, we return to the previous situation, which is a safe situation to be in. However, if we simply create a new object and assign the name to this before freeing the first object, we have the situation where the link between MyObjName and the first object is broken, to be replaced by a link between MyObjName and the new object:
MyObjName := TMyClass.Create;
...
...
MyObjName := TMyClass.Create;
If MyObjName was the only reference to the first object, breaking the link between it and MyObjName means that the first object is no longer accessible to the program. If one does not free the first object and release its memory before re-assigning MyObjName, the object continues to reside (uselessly) in memory, leading to a memory leak. A similar error, where an inaccessible object takes up memory, is to assign the object’s name to nil without first freeing the object.

Explore Delphi Programming

About.com Special Features

Build Your Own Website

Step-by-step advice on how to do everything from choosing a Web host to promoting your content. More >

Connect Your Home Computers

Easy ways to connect two computers for networking purposes. More >

Delphi Programming

  1. Home
  2. Computing & Technology
  3. Delphi Programming
  4. Coding Delphi Applications
  5. OOP in Delphi
  6. Free Online OOP Course
  7. Accessing an Object and its Data - Delphi OOP Part 4 / Chapter 8

©2009 About.com, a part of The New York Times Company.

All rights reserved.