| View previous topic :: View next topic |
| Author |
Message |
Roman Sanchez Guest
|
Posted: Thu Jan 15, 2004 10:24 pm Post subject: Switching between ref and no ref-counted interfaces |
|
|
Let's say I have an interface
IUsefulInterface = interface
....
end;
which I want to be ref. counted when using alone to forget about having to
free it. Hence I could use an implementing class:
TUseful = class(TInterfacedObject, IUsefulInterface)
....
end;
But let's say now that I also want to use the interface as part of a
container:
IContainer = interface
function GetUseful: IUsefulInterface;
property Useful: IUsefulInterface read GetUseful;
end;
If I use the same implementing object chances are that the part survive its
container.
What could I avoid this situation?
Should I have to use another, no ref. counted, implementation of
IUsefulInterface or is it possible to use the same object?
Thanks
|
|
| Back to top |
|
 |
Joanna Carter (TeamB) Guest
|
Posted: Fri Jan 16, 2004 12:15 am Post subject: Re: Switching between ref and no ref-counted interfaces |
|
|
"Roman Sanchez" <romans (AT) servidor (DOT) unam.mx> a écrit dans le message de news:
40071382$1 (AT) newsgroups (DOT) borland.com...
| Quote: | IContainer = interface
function GetUseful: IUsefulInterface;
property Useful: IUsefulInterface read GetUseful;
end;
If I use the same implementing object chances are that the part survive
its
container.
What could I avoid this situation?
Should I have to use another, no ref. counted, implementation of
IUsefulInterface or is it possible to use the same object?
|
As long as you instantiate your implementing class into an interface
reference in the class that implements the containing interface, then that
reference will be freed during the destructor of the containing class.
TContainer = class(TInterfacedObject, IContainer)
private
fUseful: IUsefulInterface;
protected
function GetUseful: IUsefulInterface;
public
constructor Create;
property Useful: IUsefulInterface read GetUseful;
end;
implementation
constructor TContainer.Create;
begin
inherited Create;
fUseful := TUseful.Create;
end;
You need for anything non-ref-counted; in fact, it would be difficult to do.
Joanna
--
Joanna Carter (TeamB)
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
Joanna Carter (TeamB) Guest
|
Posted: Fri Jan 16, 2004 8:48 am Post subject: Re: Switching between ref and no ref-counted interfaces |
|
|
Román Sánchez wrote:
| Quote: | But with this implementation the Useful property might survive to its
container if there is a reference to it in an outer scope:
var
GlobalUseful: IUseful; // global scope
procedure Inner;
var
Container: IContainer;
begin
Container := TContainer.Create;
GlbalUseful := Container.Useful;
// Here Container goes out of scope and so it is destroyed
end;
// But here Useful still references Container.Useful and hence Part is
alive, is it not?
|
Indeed, but you should not, as a matter of good practice ever use global
variables, especially to memory managed types. You would encounter the same
problems if you used a global var to hold on to a component on a form; due
to the Owner system, when the Form dies, the global component reference will
become invalid.
All global interface vars must be explicitly nilled in the finalization of
the unit, otherwise they officially present a memory leak; although in
theory Windows returns everything to the heap when the app closes.
Why do you think you need a global var?
Joanna
--
Joanna Carter (TeamB)
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
Marc Rohloff Guest
|
Posted: Fri Jan 16, 2004 1:40 pm Post subject: Re: Switching between ref and no ref-counted interfaces |
|
|
Román Sánchez wrote on Thu, 15 Jan 2004 22:40:49 -0600 ...
| Quote: | But with this implementation the Useful property might survive to its
container if there is a reference to it in an outer scope:
var
GlobalUseful: IUseful; // global scope
procedure Inner;
var
Container: IContainer;
begin
Container := TContainer.Create;
GlbalUseful := Container.Useful;
// Here Container goes out of scope and so it is destroyed
end;
|
Using a non-reference counted implementation would not help you here.
If you managed to release the object when its container was dereferenced
you would get an error when you try to use the global variable or when
the global variable went out of scope.
You would have to keep the object alive if you want to keep the global
reference to avoid problems so you either have to ensure that the
container clears the global reference when it is released, not use a
global reference, or make the container stay alive if the contained
object is still alive or possibly ensure that the contained object can
function without the container.
Marc Rohloff
marc rohloff at bigfoot dot com
|
|
| Back to top |
|
 |
Ken Revak Guest
|
Posted: Wed Jan 21, 2004 2:55 pm Post subject: Re: Switching between ref and no ref-counted interfaces |
|
|
I've grappled with this problem and have settled on the strategy of
having the container notify fUseful that it is orphaned. fUseful can
then determine how it wants to handle subsequent calls. In my case, the
outstanding references to fUsefull are usually released when the
observers discover that the container has disappeared.
Ken Revak
Román Sánchez wrote:
| Quote: | As long as you instantiate your implementing class into an interface
reference in the class that implements the containing interface, then that
reference will be freed during the destructor of the containing class.
TContainer = class(TInterfacedObject, IContainer)
private
fUseful: IUsefulInterface;
protected
function GetUseful: IUsefulInterface;
public
constructor Create;
property Useful: IUsefulInterface read GetUseful;
end;
|
|
|
| Back to top |
|
 |
Peter Morris [Droopy Eyes Guest
|
Posted: Wed Jan 21, 2004 4:14 pm Post subject: Re: Switching between ref and no ref-counted interfaces |
|
|
| Quote: | But let's say now that I also want to use the interface as part of a
container:
IContainer = interface
function GetUseful: IUsefulInterface;
property Useful: IUsefulInterface read GetUseful;
end;
|
In this case the object which implements the IUsefulInterface should descend
from TAggregatedObject.
--
Pete
=============
http://www.DroopyEyes.com - Delphi source code
Audio compression components, Fast Strings, DIB Controls
Read or write article on just about anything
http://www.HowToDoThings.com
|
|
| Back to top |
|
 |
|