tags:

views:

1014

answers:

5

It seems completely irrelevant to require a TComponent as an owner to instantiate an object of some kind. Why are there so many Delphi components that require this?

For example, TXMLDocument requires a TComponent object to instantiate.

Why is this and if there's a good reason, what should I be using in there to "do the right thing"?

+24  A: 

The owner component is supposed to manage all its owned components. The owned components gets destroyed automatically when the owner is destroyed. This helps the developer who just drags components from the tool-palette, drops them on the form and just hooks up the events to get his work done without worrying about managing the lifetime of the components.

The form is the owner of all components dropped on it. The Application object is owner of the form. When the app is closed the Application object is destroyed which in turn destroys the forms and all the components.

But the owner is not really necessary when a components is created. If you pas Nil to the parameter, the component will be created without an owner. But it will be the programmer's responsibility to manage the component's lifetime.

Great answer. So if I wanted to manage the lifetime myself, how would I make sure an object is destroyed when I'm done with it?
Dave
@prapin: Slight correction is necessary: The Application object is only owner of a form if the form has been created with Application.CreateForm(), or when Application has been passed to Create as AOwner. A form could be owned by another form, or any other component for that matter.
mghie
@Dave: Following SO questions deal with object ownership: http://stackoverflow.com/questions/398137/what-is-the-best-way-to-do-nested-try-and-finally-statement-in-delphi#399860, http://stackoverflow.com/questions/415958/how-to-automatically-free-classes-objects#415990
mghie
@Dave: Component.destroy();
Tom
+7  A: 

All TComponent descendents require Owner, it is defined in TComponent constructor. The Owner component is responsible to destroy all the Owned components.

if you want to control the life time, you can pass nil as parameter.

Cesar Romero
+3  A: 

Just to add some extra information.

Each control also has a parent. (A TWinControl). Where the owner takes care of the lifetime, the parent takes care of showing the object.

For example a form has a panel and the panel has a button. In that case, the form owns the panel and the button. But the form is the parent of the panel and the panel is the parent of the button.

Gamecat
Yes, but not all components (TComponent) are controls (TControl). TControl descends from TComponent. A component that is not a control does not have a parent.
Jim McKeeth
Also worth noting is that if you destroy a parent, the children will get destroyed, too, even if they're not owned by the parent.
Rob Kennedy
+2  A: 

There is also something else to be aware of. I have used more than a couple of third party components which rely on an Owner component being passed in the Constructor Create, and if you pass in Nil will throw an exception/AV.

The net result is that these components will work fine when you use the visually within the IDE but cause problems when they are created at run-time.

The cause of these problems is, in a sense, bad design. Nothing in the rules state you cannot/should not pass in NIL as the aOwner parameter.

Aikislave
+1  A: 

The object doesn't REQUIRE a tComponent be passed as AOwner. You can easily pass nil to this and handle the destruction yourself. Most often, I tend to use this technique for localized routines where the component being used will not be used outside of the current method. for example:

Procedure TForm1.Foo;
var
  XmlDoc : tXmlDocument;
begin
  XmlDoc := tXmlDocument.Create(nil);
  try
    // do processing of the XMLDoc here
  finally
    FreeAndNil(XmlDoc); 
  end;
end;
skamradt