On Thu, 2005-03-24 at 09:06 +0100, Michael Van Canneyt wrote: > > On Thu, 24 Mar 2005 [EMAIL PROTECTED] wrote: > > > Quoting Michael Van Canneyt <[EMAIL PROTECTED]>: > > > >> > >> > >> On Wed, 23 Mar 2005 [EMAIL PROTECTED] wrote: > >> > >>> Quoting Marco van de Voort <[EMAIL PROTECTED]>: > >>> > >>>>> On Tue, 22 Mar 2005, ml wrote: > >>>>>> // than one interface > >>>>>> a := (object as IA); // correct > >>>>>> b := (object as IB); // returns pointer to the first interface > >>> vmt=IA > >>>>>> c := (object as IC); // returns pointer to the first interface > >>> vmt=IA > >>>>>> // there's no way to do again it's like direct call to exception > >>>>>> obj := a; // returns pointer(obj) + 12 ??? > >>>>> > >>>>> This is nonsense. You cannot assign an interface to a class. > >>>>> A class IMPLEMENTS an interface, it is not an interface. > >>> > >>> Ok, its nonsense. I said it already works with my patch, but I guess you > >>> know it better. So my example down there doesn't work (with patch). You > >>> should know. > >>> I (; can't ;) transfer from one interface to other back to object and to > >>> 3rd interface. I just imagine my results. > >> > >> Tell me, what is > >> > >> obj := a; > >> > >> supposed to DO ? A class has a set of methods. Some of these methods form > >> the VMT of an interface. What your code does, is say > >> "don't use your VMT methods, use these instead' ? > > > > Yes, exactly. I even provided test example at the bottom of my previous > > message, > > where I transfered from class to IA, back to class and then to ID. And > > called > > ID.D; And it just works (this is also nice start for blind properties > > implementation, which now also became possible, since original vmt is now > > visible) > > > > But, It should be used as > > > > if (TObject(a).InheritedFrom(TSomeClass)) then begin > > obj := TSomeClass(a); // note that here obj is declared as TSomeClass > > // now safely use as this vmt > > end; > > > > if SupportsInterface(TObject(a), IB) then begin > > ibvar := a; // declared ibvar: IB > > // now safely use as this vmt > > end; > > > > in perfect world "is" would return InheritedFrom or SupportsInterface > > result and > > not actual class check, if true then all needed operations are satisfied. > > I can understand that 'is' should be able to check interfaces; this is a > useful patch. > > I also understand what your code should do. > > BUT I see some flaws in your design. > > IA = Interface > procedure InitF; > end; > > > TA = class(TObject,IA) > F : TList; > Procedure InitF; > Procedure B; > end; > > Procedure TA.InitF; > > begin > F:=Tlist.Create; > end; > > Procedure TA.B; > > begin > F.Add(SomePointer); > end; > > > Var > A : TA; > C : IA; > > begin
Completely wrong type of thinking here, and I can't answer you what you asked, so I provided answer why I can't answer and how it should be used > A:=TA.Create; > C:=SomeIA; // Get an IA interface from somewhere. Why would someone create one object just to override its variable with some other value? To create memory leaks? > A:=C; > A.InitF; // <<--- Which InitF should be used ? > A.B; // Crash or not ? :? Depends, but your example is one complete mistake of using this. It makes sense just as my example with pointer down here. So... would it crash? Yeah, probably just the same as var p, r: pchar; i: integer; begin GetMem(p, 100); for i := 0 to 10000000 do p[i] := #0; GetMem(r, 1000); p := r; // I intentionally haven't freed pointer // like you didn't in your example // So, how does pascal handle this? It can't. // Those who code should know what they do end; Question here is different. Was that my mistake as programmer or fpc mistake for not predicting my stupidity. Guess what, it wasn't fpc fault, so if some interfaced object doesn't initialize its variables, and others do. Correct the problem there and don't blame wrong implementation. > end; > If you would at least write Procedure TA.B; > > begin if F = nil then F:=TList.Create; > F.Add(SomePointer); > end; > your example would work > If TA.InitF is used, then B runs OK, but then A:=C has no meaning at all. > If the InitF from C is used, then F will not be initialized, and B will > fail. > Here we go again. Your main problem is that you don't understand (or you lack imagination) what interface is in his complete feature set. Main feature of interfaces is to have ability to predict combinations of commands that interfaces support, as I already specified... having monolithic interface structure makes no sense (you just get mirror copy of classes), it's a waste of time, paper and space. And before you answer how it is not possible, or how you don't have time to implement it. I'm game. I'm prepared to make all the necessary changes and patches. All that I would ask for is a few pointers (if that could be done on line on some irc or msn channel, that would be perfect, it's hard to talk in one e-mail a day) how and where so that I don't need to dissect complete compiler code (you probably understand that I'm not as familiar with its code as you are, that would be only few questions like "where does it...", "how does it...", "what would be the preffered implementation of ..."). Here is a simple example how it should be used type IReportable = interface function Report: string; // let's say that this should write report and // return status description as string end; ILogged = interface procedure Log(aStr: string); end; And now some completely different place in your software, main feature of interfaces is that you can predict possible features, and not even start to implement them at that moment procedure MyXYZPart.DoReport(aRep: IReportable); begin if (aRep <> nil) then begin if (aRep is ILogged) then (aRep as ILogged).Log(aRep.Report) else aRep.Report end; Meaning, that if I derived some class as (and call DoReport with it as parameter) type TSomeClass = interface(TInterfacedObject, IReportable, ILogged) this class will have to contain all the logging facility needed, and that's conditioned with interfaces (otherwise it won't be compiled). TSomeClass2 = interface(TInterfacedObject, IReportable) this class will automatically skip logging, because logging interface is not supported by class What is difference here? I could pass a simple interfaced object as parameter and predict possibility of logging. If object or interface support that option then all the facility needed is supported and logging is done. This is how and why interfaces should be used, for predicting features. And with interfaces as they are this is just impossible. I hope that you start seeing power behind more flexible interfaces ml > Michael. > > _______________________________________________ > fpc-pascal maillist - fpc-pascal@lists.freepascal.org > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal