BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Re: Interface reference vs. Object reference
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design
View previous topic :: View next topic  
Author Message
DPi
Guest





PostPosted: Thu Oct 16, 2003 7:26 am    Post subject: Re: Interface reference vs. Object reference Reply with quote



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





PostPosted: Thu Oct 16, 2003 7:30 am    Post subject: Re: Interface reference vs. Object reference Reply with quote



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





PostPosted: Thu Oct 16, 2003 9:33 am    Post subject: Re: Interface reference vs. Object reference Reply with quote



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





PostPosted: Thu Oct 16, 2003 10:09 am    Post subject: Re: Interface reference vs. Object reference Reply with quote

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





PostPosted: Thu Oct 16, 2003 12:48 pm    Post subject: Re: Interface reference vs. Object reference Reply with 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).

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





PostPosted: Thu Oct 16, 2003 1:41 pm    Post subject: Re: Interface reference vs. Object reference Reply with quote

"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





PostPosted: Thu Oct 16, 2003 2:16 pm    Post subject: Re: Interface reference vs. Object reference Reply with 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.

"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





PostPosted: Thu Oct 16, 2003 3:02 pm    Post subject: Re: Interface reference vs. Object reference Reply with quote


Quote:
I think - no.

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





PostPosted: Thu Oct 16, 2003 3:44 pm    Post subject: Re: Interface reference vs. Object reference Reply with quote


"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





PostPosted: Thu Oct 16, 2003 6:29 pm    Post subject: Re: Interface reference vs. Object reference Reply with quote

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





PostPosted: Thu Oct 16, 2003 7:36 pm    Post subject: Re: Interface reference vs. Object reference Reply with quote

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





PostPosted: Fri Oct 17, 2003 6:25 am    Post subject: Re: Interface reference vs. Object reference Reply with quote

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





PostPosted: Fri Oct 17, 2003 7:13 am    Post subject: Re: Interface reference vs. Object reference Reply with quote

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





PostPosted: Fri Oct 17, 2003 8:12 am    Post subject: Re: Interface reference vs. Object reference Reply with quote

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





PostPosted: Fri Oct 17, 2003 9:44 am    Post subject: Re: Interface reference vs. Object reference Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.