Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Object References

Status
Not open for further replies.

andy715723

Programmer
Dec 19, 2001
4
US
I have a question regarding the following code
Code:
procedure TForm1.Button1Click(Sender: TObject);
var edit : TEdit;
begin
  ShowMessage( edit.Name );
  if NOT edit.ReadOnly then
    ShowMessage( 'FALSE' );
end;
[\code]
Why does accessing these properties [b]NOT[/b] cause an access violation?  Strangely, edit.name evaluated to "Button1"

-Andy
 
That is odd. If I remove the button, and put the event on the form's mousemove, edit.name is "Form1". Brian
"There are 2 kinds of people in the world, those that divide people into two groups and those that don't. I belong to the second group." - tag line I stole
 
procedure TForm1.Button1Click(Sender: TObject);
var edit : TEdit;
begin
Edit.Top := 6;
Edit.Left := 6;
Edit.Height := 200;
Edit.Width := 200;
Edit.Visible := true;
Edit.Text := 'Why am I here';
ShowMessage( edit.Name );
if NOT edit.ReadOnly then
ShowMessage( 'FALSE' );
end;

This appears to actually create a button with the requested properties. If you remove the button and put the event on a combo box, it creates a combo box with the properties set as above. Brian
"There are 2 kinds of people in the world, those that divide people into two groups and those that don't. I belong to the second group." - tag line I stole
 
I've certainly noticed this problem when using local integer values, but did not connect it to the edit example.

This is from the google boards (really borland.public)

Message 3 in thread
From: TeamB (rick@fenestra.com_(Rick_Rogers)
Subject: Re: Testing for an object

Newsgroups: borland.public.delphi.objectpascal
Date: 1998/05/28


On Thu, 28 May 1998 10:18:45 +0200, "Iñigo Alberdi"
<eumark0@eumark.com> wrote:

> how can I test for the object to be instantiated

It depends on where you've declared and how you've used the object
reference variable.

Remember, object reference variables are nothing but 4-byte memory
address pointers to object instances. An object reference variable can
a) contain nil (which is zero); b) a memory address of a valid object
instance; or c) a memory address which doesn't point to a valid object
instance. Case (c) could result from a pointer to random memory, or a
pointer which points to an instance which has been destroyed.

In general, you will use the Assigned function to determine whether an
object instance has been instantiated. Assigned simply returns True if
the object reference variable is not nil (b or c), and False if the
variable is nil (a).

Notice that Assigned will return True for Case (c), which means
assigned can return True even if the object reference variable doesn't
point to a valid object instance. How can this be?

--- EXAMPLE 1.

Consider this example:

var
E : TExample;
begin
E := TExample.Create;
E.Free;
if Assigned(E) then
ShowMessage('Assigned=True'); // Displays
end;

The reason Assigned returns True here is that the Free method doesn't
set an object reference variable to nil (for very good and valid
reasons, which I can explain later if you are interested). So if your
application needs to test whether the E object reference variable is
nil, you'll need to set it to nil after freeing the instance:

var
E : TExample;
begin
E := TExample.Create;
E.Free;
E := nil;
if Assigned(E) then
ShowMessage('Assigned=True'); // Doesn't display
end;

This applies to any object reference variable you instantiate and then
free -- freeing does not set it to nil. So the above example pertains
to local variables, unit variables, and class fields equally.

--- EXAMPLE 2.

Also consider this example:

var
E : TExample;
begin
if Assigned(E) then
ShowMessage('Assigned=True'); // Probably will display
end;

Local variables aren't initialized to any particular value -- in
general, you must initialize them first before using them. For
example, you would want to set an integer variable to zero, a string
variable to '', etc. In this example, the local variable E isn't
initialized to anything in particular, which means it will have the
value of whatever happens to be in the stack memory at that moment.
This the memory address could be any number within range, and the
possibility that it would be zero is quite low.

So if you need to test an local variable, you should initialize it to
nil first (in the same way you would initialize an integer variable to
zero, or a string variable to ''), like this:

var
E : TExample;
begin
E := nil;
if Assigned(E) then
ShowMessage('Assigned=True'); // Doesn't display
end;

Note that only local variables aren't initialized -- object fields,
and unit variables are initialized to an empty value as appropriate
for the type. So object reference variables which are, for example,
class fields, will be initialized to nil when the object is
instantiated.

--- CONCLUSION.

This issue comes up from time to time, and honestly it perplexes me.
In all the code I've written, I've never needed to test whether an
object is instantiated -- your code created the object, so your code
should already know whether it is created without needing to test.
That being said, I hope this explanation helps you understand the
issues. The key thing to remember is to set an object reference to nil
after freeing the instance if you later need to test the object
reference.

--
Rick Rogers (TeamB) | Fenestra Technologies



Brian
&quot;There are 2 kinds of people in the world, those that divide people into two groups and those that don't. I belong to the second group.&quot; - tag line I stole
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top