Re: [fpc-pascal] Class reference doubt
On 25/11/2011 07:50, Dimitri Smits wrote: so you have: type TMyObject=class(TObject) ... constructor Create; end; Yes TMyClass = class of TMyObject; //<-- important I guess Not important or necessary. I was using TClass from RTL = class of TObject ... procedure processSomething(AClass: TClass); var someInstance: TObject; begin someInstance := AClass.Create(); //<-- always the one from TClass/TObject? end; Yes ... begin processSomething(TMyObject); end; class methods (and the constructors and destructor) are in Delphi part of the TClass memorystructure. I believe even the TObject default Create. For your trick to work, you need one of 2 things: - declare the class-reference for a type explicitly (class of T...) - make a virtual constructor in a subtype of TObject and declare a class-reference. Then you derive from that subtype. I know all of this. I even already use this approach in one of my libraries where i have a base class and a reference to class of this type. What i needed this time was more generic: the ability to instantiate any TObject without the need to change interface of the classes I don't think (did not test) it finds a TMyClass in Delphi as well if you do not declare the type, so in effect it always takes TClass. The other scenario's I've used before in classfactory pattern before. It has nothing and everything to do with RTTI. No, the new D2010+ RTTI does not give access to the default constructor (I think), Yes, it does see example at http://code.google.com/p/emballo/source/browse/trunk/Src/Emballo.DI.Instantiator.pas#152 Anyway, i already found a solution, so there's no fuzz in my part Luiz ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
- "Luiz Americo Pereira Camara" schreef: > On 24/11/2011 19:34, Jonas Maebe wrote: > > In that case, you did not hit the same problem as the original > poster (your "I also hit this problem recently" is what triggered my > response). His problem was that if you call a non-virtual constructor > on a class reference variable, that the constructor is determined > based on the static type of the class reference rather than on the > dynamic type. > > It does not matter much but i hit the same problem. Just replace class > > of TObj by class of TObject (TClass) > > I stored a class (TMyClass) in a class variable (AClass: TClass). I > was > expecting that calling AClass.Create would call TMyClass.Create. Just > > like him i found that is not the case. > > To be clear: i'm not saying that is a bug or asking for changing the > behavior > so you have: type TMyObject=class(TObject) ... constructor Create; end; TMyClass = class of TMyObject; // <-- important I guess ... procedure processSomething(AClass: TClass); var someInstance: TObject; begin someInstance := AClass.Create(); // <-- always the one from TClass/TObject? end; ... begin processSomething(TMyObject); end; class methods (and the constructors and destructor) are in Delphi part of the TClass memorystructure. I believe even the TObject default Create. For your trick to work, you need one of 2 things: - declare the class-reference for a type explicitly (class of T...) - make a virtual constructor in a subtype of TObject and declare a class-reference. Then you derive from that subtype. I don't think (did not test) it finds a TMyClass in Delphi as well if you do not declare the type, so in effect it always takes TClass. The other scenario's I've used before in classfactory pattern before. It has nothing and everything to do with RTTI. No, the new D2010+ RTTI does not give access to the default constructor (I think), but it IS part of the TClass-alike-structure that is generated for the TObject descendant. kind regards, Dimitri Smits ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
On 24/11/2011 19:34, Jonas Maebe wrote: In that case, you did not hit the same problem as the original poster (your "I also hit this problem recently" is what triggered my response). His problem was that if you call a non-virtual constructor on a class reference variable, that the constructor is determined based on the static type of the class reference rather than on the dynamic type. It does not matter much but i hit the same problem. Just replace class of TObj by class of TObject (TClass) I stored a class (TMyClass) in a class variable (AClass: TClass). I was expecting that calling AClass.Create would call TMyClass.Create. Just like him i found that is not the case. To be clear: i'm not saying that is a bug or asking for changing the behavior The task is accomplished by other means See http://code.google.com/p/emballo/source/browse/trunk/Src/Emballo.DI.Instantiator.pas#152 That's indeed a completely different technique to dynamically instantiate classes (and if you don't really need that kind of flexibility, I would recommend virtual constructors instead since they're much simpler and faster). I will do in a third way, that keeps flexibility (and is also fast) but requires more typing. Luiz ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
On 24 Nov 2011, at 23:00, Luiz Americo Pereira Camara wrote: > On 24/11/2011 08:02, Jonas Maebe wrote: >> >> On 24 Nov 2011, at 02:58, Luiz Americo Pereira Camara wrote: >> >>> On 23/11/2011 18:48, Jesus Reyes wrote: where I would expect: cls class is TFoo TObj.create TFoo.create >>> >>> I also hit this problem recently >>> >>> Found that this is one limitation of fpc. Under newer delphi it's possible >>> to get the expected behavior without forcing programmer to create a virtual >>> constructor by using the new RTTI >> >> I find it very hard to believe that the behaviour of existing code like that >> would suddenly change (and hence potentially break programs) simply because >> extra RTTI is added. > > It does not change. In that case, you did not hit the same problem as the original poster (your "I also hit this problem recently" is what triggered my response). His problem was that if you call a non-virtual constructor on a class reference variable, that the constructor is determined based on the static type of the class reference rather than on the dynamic type. > The task is accomplished by other means > > See > http://code.google.com/p/emballo/source/browse/trunk/Src/Emballo.DI.Instantiator.pas#152 That's indeed a completely different technique to dynamically instantiate classes (and if you don't really need that kind of flexibility, I would recommend virtual constructors instead since they're much simpler and faster). Jonas___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
On 24/11/2011 05:47, Graeme Geldenhuys wrote: On 2011-11-24 03:58, Luiz Americo Pereira Camara wrote: possible to get the expected behavior without forcing programmer to create a virtual constructor by using the new RTTI What has the "new RTTI" got to do with anything? Simply define TObj.Create as virtual, and TFoo.Create as overridden. This is rather normal coding practise with classes. Nothing special. This solution is not quite generic because is necessary to descend from an specific class and also needs to change an interface declaration. So to use in old code / classes it would be necessary to change the hierarchy and the interface. Also it would not work with classes that i cant change the hierarchy like rtl ones or third party With Delphi is possible to call a constructor even if has a different name from Create and with parameters without changing interface or hierarchy It seems useful for me Luiz 8<-8<-8<-8<-8< program test; {$mode ObjFpc}{$H+} type TObj = class public constructor create; virtual; end; TObjClass=class of TObj; TFoo = class(TObj) public constructor create; override; end; constructor TObj.Create; begin inherited create; WriteLn('TObj.create'); end; constructor TFoo.create; begin inherited Create; WriteLn('TFoo.Create'); end; var cls: TObjClass; obj: TObj; begin cls := TFoo; WriteLn('cls class is ',cls.ClassName); Obj := cls.Create; Obj.Free; end. 8<-8<-8<-8<-8< And here is the output... $ ./test cls class is TFoo TObj.create TFoo.Create Regards, - Graeme - ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
On 24/11/2011 08:02, Jonas Maebe wrote: On 24 Nov 2011, at 02:58, Luiz Americo Pereira Camara wrote: On 23/11/2011 18:48, Jesus Reyes wrote: in the following example The output is: cls class is TFoo TObj.create where I would expect: cls class is TFoo TObj.create TFoo.create I also hit this problem recently Found that this is one limitation of fpc. Under newer delphi it's possible to get the expected behavior without forcing programmer to create a virtual constructor by using the new RTTI I find it very hard to believe that the behaviour of existing code like that would suddenly change (and hence potentially break programs) simply because extra RTTI is added. It does not change. The task is accomplished by other means See http://code.google.com/p/emballo/source/browse/trunk/Src/Emballo.DI.Instantiator.pas#152 Luiz ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
On 24 Nov 2011, at 02:58, Luiz Americo Pereira Camara wrote: On 23/11/2011 18:48, Jesus Reyes wrote: in the following example The output is: cls class is TFoo TObj.create where I would expect: cls class is TFoo TObj.create TFoo.create I also hit this problem recently Found that this is one limitation of fpc. Under newer delphi it's possible to get the expected behavior without forcing programmer to create a virtual constructor by using the new RTTI I find it very hard to believe that the behaviour of existing code like that would suddenly change (and hence potentially break programs) simply because extra RTTI is added. Jonas ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
On 2011-11-24 03:58, Luiz Americo Pereira Camara wrote: > possible to get the expected behavior without forcing programmer to > create a virtual constructor by using the new RTTI What has the "new RTTI" got to do with anything? Simply define TObj.Create as virtual, and TFoo.Create as overridden. This is rather normal coding practise with classes. Nothing special. 8<-8<-8<-8<-8< program test; {$mode ObjFpc}{$H+} type TObj = class public constructor create; virtual; end; TObjClass=class of TObj; TFoo = class(TObj) public constructor create; override; end; constructor TObj.Create; begin inherited create; WriteLn('TObj.create'); end; constructor TFoo.create; begin inherited Create; WriteLn('TFoo.Create'); end; var cls: TObjClass; obj: TObj; begin cls := TFoo; WriteLn('cls class is ',cls.ClassName); Obj := cls.Create; Obj.Free; end. 8<-8<-8<-8<-8< And here is the output... $ ./test cls class is TFoo TObj.create TFoo.Create Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
On 23/11/2011 18:48, Jesus Reyes wrote: in the following example The output is: cls class is TFoo TObj.create where I would expect: cls class is TFoo TObj.create TFoo.create I also hit this problem recently Found that this is one limitation of fpc. Under newer delphi it's possible to get the expected behavior without forcing programmer to create a virtual constructor by using the new RTTI Luiz ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Class reference doubt
On 23 Nov 2011, at 22:48, Jesus Reyes wrote: > in the following example The output is: > cls class is TFoo > TObj.create > > where I would expect: > cls class is TFoo > TObj.create > TFoo.create > > ie the TFoo.constructor is not called, is this normal/expected? Yes. You have to use a virtual constructor if you wish to override in a child class, just like with regular methods and class methods. Jonas___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Class reference doubt
in the following example The output is: cls class is TFoo TObj.create where I would expect: cls class is TFoo TObj.create TFoo.create ie the TFoo.constructor is not called, is this normal/expected?, The documentation does clarify the situation: http://www.freepascal.org/docs-html/ref/refse31.html "Class reference types are used to create instances of a certain class, which is not yet known at compile time, but which is specified at run time. Essentially, a variable of a class reference type contains a pointer to the definition of the speficied class. This can be used to construct an instance of the class corresponding to the definition, or to check inheritance." Thanks. Jesus Reyes A. program test; {$mode ObjFpc}{$H+} type TObj = class public constructor create; end; TObjClass=class of TObj; TFoo = class(TObj) public constructor create; end; constructor TObj.Create; begin inherited create; WriteLn('TObj.create'); end; constructor TFoo.create; begin inherited Create; WriteLn('TFoo.Create'); end; var cls: TObjClass; obj: TObj; begin cls := TFoo; WriteLn('cls class is ',cls.ClassName); Obj := cls.Create; Obj.Free; end. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal