0% found this document useful (0 votes)
13 views4 pages

The Object Reference Model: 198 - 07: Objects

Uploaded by

skamelrech2020
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views4 pages

The Object Reference Model: 198 - 07: Objects

Uploaded by

skamelrech2020
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

198 - 07: Objects

The notation used is nothing unusual, but it is powerful. We can write a complex
function (such as LeapYear) and then access its value for every TDate object as if it
were a primitive data type. Notice that ADay.LeapYear is an expression similar to
ADay.Year, although the first is a function call and the second a direct data access.
As we’ll see in Chapter 10, the notation used by Object Pascal to access properties is
again the same.

note Calls of methods with no parameters in most programming languages based on the C language
syntax require parenthesis, like in ADay.LeapYear(). This syntax is legal also in Object Pascal,
but rarely used. Methods with no parameters are generally called without the parenthesis. This is
very different from many languages in which a reference to a function or method with no paren-
thesis returns the function address. As we have see in the section “Procedural Types” in Chapter 4,
Object Pascal uses the same notation for calling a function or reading its address, depending on
the context of the expression.

The output of the code snippet above is fairly trivial:


Leap year: 2016
Again, let me compare the object creation with similar code written in other pro-
gramming languages:
// C# and Java languages (object reference model)
Date aDay = new Date();

// C++ language (two alternative styles)


Date aDay; // local allocation
Date* aDay = new Date(); // "manual" reference

The Object Reference Model


In some OOP languages like C++, declaring a variable of a class type creates an
instance of that class (more or less like it happens with records in Object Pascal).
The memory for a local object is taken from the stack, and released when the func-
tion terminates. In most cases, though, you have to explicitly use pointers and
references to have more flexibility in managing the lifetime of an object, adding a lot
of extra complexity.
The Object Pascal language, instead, is based on an object reference model, exactly
like Java or C#. The idea is that each variable of a class type does not hold the actual
value of the object with its data (to store the day, month, and year, for example).
Rather, it contains only a reference, or a pointer, to indicate the memory location
where the actual object data is stored.

Marco Cantù, Object Pascal Handbook


07: Objects - 199

note In my opinion, adopting the object reference model was one of the best design decisions made by
the compiler team in the early days of the language, when this model wasn't so common in pro-
gramming languages (in fact, at the time Java wasn't available and C# didn't exist).

This is why in these languages you need to explicitly create an object and assign it to
a variable, as objects are not automatically initialized. In other words, when you
declare a variable, you don’t create an object in memory, you only reserve the mem-
ory location for a reference to the object. Object instances must be created manually
and explicitly, at least for the objects of the classes you define. (In Object Pascal,
though, instances of components you place on a form are built automatically by the
run time library.)
In Object Pascal, to create an instance of an object, we can call its special Create
method, which is a constructor or another custom constructor defined by the class
itself. Here is the code again:
ADay := TDate.Create;
As you can see, the constructor is applied to the class (the type), not to the object
(the variable). That's because you are asking the class to create a new instance of its
type, and the result is a new object you'd generally assign to a variable.
Where does the Create method come from? It is a constructor of the class TObject,
from which all the other classes inherit, so it is universally available. It is very com-
mon to add custom constructors to your classes, though, as we'll see later in this
chapter.

Disposing Objects and ARC


In languages that use an object reference model, you need a way to create an object
before using it, and you also need a means of releasing the memory it occupies when
it is no longer needed. If you don't dispose of it, you end filling up memory with
objects you don’t need any more, causing a problem known as a memory leak. To
solve this issue languages like C# and Java, based on a virtual execution environ-
ment (or virtual machine) adopt garbage collection. While this make developer's life
easier, however this approach is subject to some complex performance-related
issues that it isn't really relevant in explaining Object Pascal. So interesting as the
issues are I don't want to delve into them here.
In Object Pascal, you generally release the memory of an object by calling its special
Free method (again, a method of TObject, available in each class). Free removes the
object from memory after calling its destructor (which can have special clean up
code). So you can complete the code snippet above as:

Marco Cantù, Object Pascal Handbook


200 - 07: Objects

var
ADay: TDate;
begin
// create
ADay := TDate.Create;
// use
...
// free the memory
ADay.Free;
end;
While this is the standard approach, the component library adds concepts like object
ownership to significantly lessen the impact of manual memory management, mak-
ing this a relatively simple issue to handle.
To further simplify memory management, the Object Pascal compilers for the
mobile platforms introduce an additional mechanism called Automatic Reference
Counting (or ARC). The ARC model uses reference counting and some other
advanced techniques to automatically dispose of objects that are not needed any
longer (or have no references pointing to them). So on these platforms, the call to
Free an object is generally superfluous: as the execution of the code above reaches
the end statement, the ADay variable goes out of scope and the referenced object is
automatically deleted. In any case, if you keep the Free statement in the code, it
does no harm at all and everything will work smoothly both with the desktop and
mobile compilers.

note Automatic Reference Counting (ARC) is a standard memory management technique for iOS
development in Objective-C and Swift, the preferred languages in Apple's Xcode. Object Pascal
borrowed from that model, including weak references and other elements, but extends it in a few
ways and has a very efficient implementation.

There is much more to memory management and ARC that you need to know, but
given this is a rather important topic and not a simple one, I decided to offer only a
short introduction here and have a full chapter focused on this topic, namely Chap-
ter 13. In that chapter I'll show you in detail the different techniques used on each
platform and those that work across all platforms.

What's Nil?
As I've mentioned, a variable can refer to an object of a given class. But it might not
be initialized yet, or the object it used to refer to might not be available any longer.
This is where you can use nil. This is a constant value indicating that the variable is
not assigned to any object (or it is assigned to a 0 memory location). When a variable
of a class type has no value, you can initialize it this way:

Marco Cantù, Object Pascal Handbook


07: Objects - 201

ADay := nil;
To check if an object has been assigned the variable, you can write either of the fol-
lowing expressions:
if ADay <> nil then ...
if Assigned (ADay) then ...
Do not make the mistake of assigning nil to an object to remove it from memory.
Setting an object to nil and freeing it are two different operations, at least on the
desktop compilers (ARC makes things a little different and it might free an object
when you set a reference to nil). So you often need to both free an object and set its
reference to nil, or call a special purpose procedure that does both operations at
once, called FreeAndNil. Again, more information and some actual demos will be
coming in Chapter 13.

Records vs. Classes in Memory


As I've mentioned earlier, one of the main differences between records and objects
relates to their memory model. Record type variables use local memory, they are
passed as parameters to functions by value by default, and they have a “copy by
value” behavior on assignments. This contrasts with class type variables that are
allocated on the dynamic memory heap, are passed by reference, and have a “copy
by reference” behavior on assignments (thus copying the reference to the same
object in memory, not the actual data).

note A consequence of this different memory management is that records lack inheritance and poly-
morphisms, two features we'll be focusing on in the next chapter.

For example, when you declare a record variable on the stack, you can start using it
right away, without having to call its constructor. This means record variables are
leaner (and more efficient) on the memory manager than regular objects, as they do
not participate in the management of the dynamic memory and ARC. These are the
key reasons for using records instead of objects for small and simple data structures.
Regarding the difference in the way records and objects are passed as parameters,
consider that the default is to make a full copy of the memory block representing the
record (including all of its data) or of the reference to the object (while the data is
not copied). Of course, you can use var or const record parameters to modify the
default behavior for passing record type parameters.

Marco Cantù, Object Pascal Handbook

You might also like