 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
DPi Guest
|
Posted: Thu Oct 16, 2003 7:26 am Post subject: Re: Interface reference vs. Object reference |
|
|
When You have several different classes implementing some Interface. You can
pass different objects to generic functions. i.e. Move(IMovable).
To the functions which are specific for some kind of objects You use object
reference. Animate(TAnimation)
"Petter Holmström" <petter.holmstrom (AT) JUNK-BUSTERparnet (DOT) fi> wrote
| Quote: | Hello everybody,
Let's say I have an interface declaration like this:
IMyInterface = interface
[...]
function MyMethod(MyVar: string): Boolean;
end;
My object declaration looks like this;
TMyObject = class(TInterfacedObject, IMyInterface)
public
function MyMethod(MyVar: string): Boolean;
end;
My question is: When should I access the object via an Interface
reference,
like this:
function ProcessObject(AObject: IMyInterface): Boolean
and when should I use an object reference such as:
function ProcessObject(AObject: TMyObject): Boolean
Also, are there any situations where one should not use interfaces?
Thanks in advance,
-Petter-
|
|
|
| Back to top |
|
 |
Joanna Carter Guest
|
Posted: Thu Oct 16, 2003 7:30 am Post subject: Re: Interface reference vs. Object reference |
|
|
Petter Holmström wrote:
| Quote: | My question is: When should I access the object via an Interface
reference, like this:
function ProcessObject(AObject: IMyInterface): Boolean
and when should I use an object reference such as:
function ProcessObject(AObject: TMyObject): Boolean
|
If youo want to retain your sanity and not have to search for memory leaks
or access violations, then you should never mix interface and object
references in Delphi.
There are lifetime management issues that play serious havoc with one's
sense of well-being :-)
Also you should always use a const modifier for interface parameters to
avoid triggering reference counting on the way in to and out of the method
that takes the parameter.
Joanna
--
Joanna Carter
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
Ignacio Vazquez Guest
|
Posted: Thu Oct 16, 2003 9:33 am Post subject: Re: Interface reference vs. Object reference |
|
|
Hello, Petter!
You wrote on Thu, 16 Oct 2003 11:59:39 +0300:
| Quote: | In other words it is either-or but not both???
|
Correct, unless you're extremely careful and know exactly what you're doing.
| Quote: | Is it also true that I never have to call Free on an interfaced object
(because everytime I try I get an Invalid Pointer Operation exception...)?
|
.._Release is called whenever an interface reference goes out of scope, and
..Free is called whenever the reference count reaches zero, so never call
either of these (or ._AddRef as well) directly.
Cheers.
Ignacio
|
|
| Back to top |
|
 |
Joanna Carter Guest
|
Posted: Thu Oct 16, 2003 10:09 am Post subject: Re: Interface reference vs. Object reference |
|
|
Petter Holmström wrote:
| Quote: | | In other words it is either-or but not both???
|
Yes
| Quote: | | Is it also true that I never have to call Free on an interfaced object
|
Yes
| Quote: | One more question: In an OPF, does this mean I have to create a different
interface for each business object, like this:
|
Yes, but you might like to consider delegating IPersistable to an
implementing class and aggregating that into business classes.
IPersistable = interface
[..]
function GetState: TMyState;
function GetObjectID: Longword;
function GetTypeID: Longword;
end;
ICustomer = interface
[..]
function GetCustomer: string;
procedure SetCustomer(Value: string);
function GetCustNo: integer;
procedure SetCustNo(Value: string);
end;
TPersistable = class(TInterfacedObject, IPersistable)
private
....
fController: Pointer;
protected
function QueryInterface(const IID: TGUID; out Obj): HResult; override;
stdcall;
public
constructor Create(const Controller: IInterface);
end;
constructor TPersistable.Create(const Controller: IInterface);
begin
inherited Create;
fController := Pointer(Controller);
end;
function TPersistable.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if IsEqualGUID(IID, IPersistable) then
begin
IPersistable(Obj) := self;
Result := S_OK;
end
else
Result := IInterface(fController).QueryInterface(IID, Obj);
end;
TCustomer = class(TInterfacedObject, ICustomer, IPersistable)
private
// ICustomer stuff
// IPersistable
fPersistable: IPersistable;
property Persistable: IPersistable
read fPersistable
implements IPersistable;
public
constructor Create;
end;
constructor TCustomer.Create;
begin
inherited Create;
fPersistable := TPersistable.Create;
end;
This way, you will only write the IPersistable implementation once. The
delegation will mean you have a ICustomar reference that can be cast to a
IPersistable and the 'controller' means that you cast the other way.
Joanna
--
Joanna Carter
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
DPi Guest
|
Posted: Thu Oct 16, 2003 12:48 pm Post subject: Re: Interface reference vs. Object reference |
|
|
Oh. We should mention here that Interfaces can eiter use or not reference
counting. In the case WITH reference counting You are right. But in other
case interfaces have a little different meaning for object oriented design.
That was what i wrote about in my earlier post. Also W/O reference counting
You can use both referencing types, and have great object oriented design in
your apps (just use conventional Freeing).
Darius
Lithuania
"Joanna Carter" <joannac (AT) btinternet (DOT) com> wrote
| Quote: | If youo want to retain your sanity and not have to search for memory leaks
or access violations, then you should never mix interface and object
references in Delphi.
|
|
|
| Back to top |
|
 |
John Elrick Guest
|
Posted: Thu Oct 16, 2003 1:41 pm Post subject: Re: Interface reference vs. Object reference |
|
|
"DPi" <DPi (AT) TAkasLT (DOT) LT> wrote
| Quote: | Oh. We should mention here that Interfaces can eiter use or not reference
counting. In the case WITH reference counting You are right. But in other
case interfaces have a little different meaning for object oriented
design.
That was what i wrote about in my earlier post. Also W/O reference
counting
You can use both referencing types, and have great object oriented design
in
your apps (just use conventional Freeing).
|
Not that easy. You can get very hard to detect random errors by mixing
Interfaces and Objects...even if they are not reference counted.
The problem is that _Release is called on the interface reference when it is
nilled or goes out of scope...even if the underlying object has already been
destroyed.
The short answer is that, if you mix them ALWAYS nil the interface reference
yourself, never let the compiler handle it, or it may do so on an invalid
address that has already been destroyed.
John
|
|
| Back to top |
|
 |
DPi Guest
|
Posted: Thu Oct 16, 2003 2:16 pm Post subject: Re: Interface reference vs. Object reference |
|
|
Do I need to Nil them if I'm using approach as said in Help "you can
implement the IInterface _AddRef and _Release methods as empty functions to
bypass the interface reference counting mechanism"?
I think - no.
"John Elrick" <jelrick (AT) adelphia (DOT) net> wrote
| Quote: | The short answer is that, if you mix them ALWAYS nil the interface
reference
yourself, never let the compiler handle it, or it may do so on an invalid
address that has already been destroyed.
|
|
|
| Back to top |
|
 |
Franz-Leo Chomse Guest
|
Posted: Thu Oct 16, 2003 3:02 pm Post subject: Re: Interface reference vs. Object reference |
|
|
The answer is wrong.
The problem is that you can't control the position in a method were
the compiler adds its cleanup code. If it is run AFTER you have
freed the implementing object by your code you are in trouble.
Regards from Germany
Franz-Leo
|
|
| Back to top |
|
 |
John Elrick Guest
|
Posted: Thu Oct 16, 2003 3:44 pm Post subject: Re: Interface reference vs. Object reference |
|
|
"DPi" <DPi (AT) TAkasLT (DOT) LT> wrote
| Quote: | Do I need to Nil them if I'm using approach as said in Help "you can
implement the IInterface _AddRef and _Release methods as empty functions
to
bypass the interface reference counting mechanism"?
I think - no.
|
You think...incorrectly.
The problem is that the interface left to its own devices, may go out of
scope _after_ the object is destroyed. Going out of scope calls a _Release
which will cause an Invalid Pointer Operation if the object has been
destroyed.
John
|
|
| Back to top |
|
 |
mike Guest
|
Posted: Thu Oct 16, 2003 6:29 pm Post subject: Re: Interface reference vs. Object reference |
|
|
Joanna Carter wrote:
| Quote: |
TPersistable = class(TInterfacedObject, IPersistable)
private
...
fController: Pointer;
protected
function QueryInterface(const IID: TGUID; out Obj): HResult; override;
stdcall;
public
constructor Create(const Controller: IInterface);
end;
|
QueryInterface function (and neither _AddRef nor _Release, for that matter)
is not declared as virtual in TInterfacedObject, so you can't override it.
At least, in D7 Pro.
Mike.
|
|
| Back to top |
|
 |
Joanna Carter Guest
|
Posted: Thu Oct 16, 2003 7:36 pm Post subject: Re: Interface reference vs. Object reference |
|
|
mike wrote:
| Quote: | QueryInterface function (and neither _AddRef nor _Release, for that
matter) is not declared as virtual in TInterfacedObject, so you can't
override it. At least, in D7 Pro.
|
Sorry, I just copied TInterfacedPersistentfrom Classes.pas and changed the
virtual to override; not something I would normally do, but I didn't take
long enough to check.
:-)
Joanna
--
Joanna Carter
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
DPi Guest
|
Posted: Fri Oct 17, 2003 6:25 am Post subject: Re: Interface reference vs. Object reference |
|
|
I don't understand You guys...
I have'nt it tested specialy in Delphi, but I think it works like in C++:
you can call functions (methods) of objects because they are not in the same
place as (deleted) object. There is only one instance of each function in
different place. And You'll get exception ONLY if you try to access objects
internal data, which woul'd be deleted. In case I rewrite _Release as empty
function, I won't get any exceptions.
Simply try it : to call function on deleted object like
function TFooClass.Add(a: Integer; b: Integer): integer;
begin
Result := a + b;
end;
I'll try it too.
"John Elrick" <jelrick (AT) adelphia (DOT) net> wrote
| Quote: | You think...incorrectly.
The problem is that the interface left to its own devices, may go out of
scope _after_ the object is destroyed. Going out of scope calls a
_Release
which will cause an Invalid Pointer Operation if the object has been
destroyed.
John
|
|
|
| Back to top |
|
 |
Joanna Carter Guest
|
Posted: Fri Oct 17, 2003 7:13 am Post subject: Re: Interface reference vs. Object reference |
|
|
DPi wrote:
| Quote: | I don't understand You guys...
I have'nt it tested specialy in Delphi, but I think it works like in C++:
|
Delphi is not the same as C++ when it comes to object lifetime management,
if you haven't tried it, then don't give advice for Delphi based on C++
knowledge.
C++ has garbage collection, Delphi does not.
Joannna
--
Joanna Carter
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
DPi Guest
|
Posted: Fri Oct 17, 2003 8:12 am Post subject: Re: Interface reference vs. Object reference |
|
|
Oh my god. Don't You really have any idea about memory management?
Not even in Delphi? At first: C++ does'nt have garbage collection - same as
Delphi. Second: (same as in C++) You can call functions of freed objects
unless they are accessing internal object data. See my earlier example.
Although that is not a proper techniqe and may lead to unreadable code. As I
mentioned earlier (why do I need to teach You again?) functions are
addressed differently than objects and are located not depending of any
particular object address. So feel safe when calling empty functions (like
_Release) on deleted objects.
Darius, M 24
Lithuania
"Joanna Carter" <joannac (AT) btinternet (DOT) com> wrote
| Quote: | C++ has garbage collection, Delphi does not.
Joannna
--
Joanna Carter
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
|
| Back to top |
|
 |
Joanna Carter Guest
|
Posted: Fri Oct 17, 2003 9:44 am Post subject: Re: Interface reference vs. Object reference |
|
|
DPi wrote:
| Quote: | Don't You really have any idea about memory management?
|
More than you seem to assume. We have a saying here: 'Please don't tell you
grandmother how to suck eggs' :-)
| Quote: | At first: C++ does'nt have garbage collection - same
as Delphi.
|
Then you had better tell Bjarne Stroustroup, the creator of C++, because he
states that certain implementations have GC in his book on C++.
| Quote: | Second: (same as in C++) You can call functions of freed
objects unless they are accessing internal object data. See my earlier
example. Although that is not a proper techniqe and may lead to
unreadable code.
|
That has been discussed many times in these groups and is always advised
against. Such practices will not port to .NET
| Quote: | As I mentioned earlier (why do I need to teach You
again?) functions are addressed differently than objects and are located
not depending of any particular object address. So feel safe when calling
empty functions (like _Release) on deleted objects.
|
If you leave empty methods for _AddRef and _Release in Delphi and only
instantiate the object into an interface reference, Destroy will never be
called and the object will never be returned to the heap, thus creating a
memory leak.
If you do not create an object reference before obtaining an interface
reference, there is no way to free the allocation because you can't cast an
interface to an object to circumvent the lack of assignment of the original
allocation to an object reference.
Then you have the sceanario where C# has and Delphi for.NET will have
garbage collection and now you have to go through all your non-standard code
and conditionally compile all your _AddRef and _Release methods because: 1.
they are not needed, and 2. stdcall methods are not allowed in .NET
languages.
Joanna
--
Joanna Carter
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|