Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2005-04

problem with "is" operator

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Linuxer Wang

Hello,

Can anybody tell me how can I know which specific type an instance of class is? The "is" operator seems weird when interface is used.

Suppose TMyInterface is a interface, and classes TCircle and TSquar both implements TMyInterface, and inst:TMyInterface, inst := TCircle.Create. How can I know which instance is inst? The following code can not even compile:

if inst is TCircle then ...

class type expected, but got "TMyInterface"
Incompatible type for arg no. 2: Got "TMyInterface", expected "TObject"

Thanks

Reply by email

DrDiettrich
to Linuxer Wang
Linuxer Wang wrote 5 lines
Hello, Can anybody tell me how can I know which specific type an instance of class is?

Check the ClassType or ClassName.

The "is" operator seems weird when interface is used.

Add a GetObject method to your interfaces, that returns the object that implements the interface. Then you can use the class specific checks.

DoDi

Reply by email

Tom Verhoeff
to Linuxer Wang: Can anybody tell me how can I know which specific type an instance of class is? The "is"…
Linuxer Wang wrote 6 lines
Can anybody tell me how can I know which specific type an instance of class is? The "is" operator seems weird when interface is used. Suppose TMyInterface is a interface, and classes TCircle and TSquar both implements TMyInterface, and inst:TMyInterface, inst :=

It does not seem right to declare var inst: TMyInterface if you want inst to have circles and squares as values. I would expect that you also have a class TFigure, of which TCircle and TSquare both are descendants. These could also implement TMyInterface.

You then declare var inst: TFigure and can do inst := TCircle.Create.
Show quoted text 7 lines
TCircle.Create. How can I know which instance is inst? The following code can not even compile: if inst is TCircle then ... class type expected, but got "TMyInterface" Incompatible type for arg no. 2: Got "TMyInterface", expected "TObject"

The type of inst needs to be a class type (such as TFigure above), not an interface object type. If you do as I suggest above, it should work.

Tom

E-MAIL: T.Verhoeff @ TUE.NL | Fac. of Math. & Computing Science PHONE: +31 40 247 41 25 | Eindhoven University of Technology FAX: +31 40 247 54 04 | PO Box 513, NL-5600 MB Eindhoven http://www.win.tue.nl/~wstomv/ | The Netherlands

Reply by email

Uberto Barbini
to Tom Verhoeff
Show quoted text 6 lines
It does not seem right to declare var inst: TMyInterface if you want inst to have circles and squares as values. I would expect that you also have a class TFigure, of which TCircle and TSquare both are descendants. These could also implement TMyInterface. You then declare var inst: TFigure and can do inst := TCircle.Create.

If so, why bother with Interfaces?
You need interfaces exactly when you cannot define a common ancestor for two classes with similar behavior.

The classical example is IFly implented by TBat and TSwallow.

Show quoted text 10 lines
> TCircle.Create. How can I know which instance is inst? The following > code can not even compile: > > if inst is TCircle then ... > > class type expected, but got "TMyInterface" > Incompatible type for arg no. 2: Got "TMyInterface", expected "TObject" The type of inst needs to be a class type (such as TFigure above), not an interface object type. If you do as I suggest above, it should work.

if inst is TCircle then ...

I don't think this can possibly work in fpc or Delphi. Apart tecnical problems, it'd be plainly wrong: using interfaces you lost the rights to know the original class.

Sometimes I added a GetUnderObject() to my interfaces to get the actual object. But it's a choice up to the interface author. BTW I needed it to release the object through the interface. I suspect that if you shouldn't ever need to know the actual class when using interfaces (maybe apart debug reasons).

Bye Uberto

Reply by email

Linuxer Wang
to Uberto Barbini
Uberto Barbini wrote 44 lines
>It does not seem right to declare var inst: TMyInterface if you >want inst to have circles and squares as values. I would expect >that you also have a class TFigure, of which TCircle and TSquare >both are descendants. These could also implement TMyInterface. > >You then declare var inst: TFigure and can do inst := TCircle.Create. > > If so, why bother with Interfaces? You need interfaces exactly when you cannot define a common ancestor for two classes with similar behavior. The classical example is IFly implented by TBat and TSwallow. >>TCircle.Create. How can I know which instance is inst? The following >>code can not even compile: >> >>if inst is TCircle then ... >> >>class type expected, but got "TMyInterface" >>Incompatible type for arg no. 2: Got "TMyInterface", expected "TObject" >> >> >The type of inst needs to be a class type (such as TFigure above), not >an interface object type. If you do as I suggest above, it should work. > > if inst is TCircle then ... I don't think this can possibly work in fpc or Delphi. Apart tecnical problems, it'd be plainly wrong: using interfaces you lost the rights to know the original class. Sometimes I added a GetUnderObject() to my interfaces to get the actual object. But it's a choice up to the interface author. BTW I needed it to release the object through the interface. I suspect that if you shouldn't ever need to know the actual class when using interfaces (maybe apart debug reasons).

I don't agree with you fully. Let's have a look at java, its "instanceof" semantic is complete. But the "is" semantic of FPC is not complete.
What you said maybe true in design patterns, but not so true in language sematics.

Show quoted text 9 lines
Bye Uberto _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Uberto Barbini
to Linuxer Wang
Show quoted text 11 lines
>Sometimes I added a GetUnderObject() to my interfaces to get the actual >object. But it's a choice up to the interface author. >BTW I needed it to release the object through the interface. >I suspect that if you shouldn't ever need to know the actual class when > using interfaces (maybe apart debug reasons). I don't agree with you fully. Let's have a look at java, its "instanceof" semantic is complete. But the "is" semantic of FPC is not complete. What you said maybe true in design patterns, but not so true in language sematics.

Java, .net, python use "late binding". Delphi, fpc and C++ no. "late binding" is very useful but definitely slow. Maybe Delphi interfaces could have retained a pointer to the underlying object, but they didn't.
As a matter of fact there was an article on DelphiMagazine to show how to grab the vmt of the object of an interface, via dirty magic of pointers arithmetics.
Maybe in fpc it'd be in a cleaner way, but why?

Bye Uberto

Reply by email