Re: [fpc-pascal] Understanding virtual methods
On 20/08/2013 07:32, Xiangrong Fang wrote: Thanks. Do you mean that the rules I see in the document apply to NORMAL virtual methods, but not virtual constructors? for all the rest, you should look for a tutorial. it is to complex for the mailing list ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Understanding virtual methods
On 20/08/2013 07:32, Xiangrong Fang wrote: Thanks. Do you mean that the rules I see in the document apply to NORMAL virtual methods, but not virtual constructors? They apply to constructors too. But... A virtual/overridden method is looked up based on the class used in code TDerived.create; // the class given is TDerived var b: TBase; b := TDerived.create; // the class given still is TDerived the assignment has nothing do to, what you class the method is called on. b.Foo(); // Foo il looked up based on TBase if b contains an instance of TDerived, then it depends on Foo being virtual. Also, I have a related question: it seems that to override methods in ancestor it is required that the method has same signature, however reintroduce will not have such limitations. Example: constructor TBase.Create; virtual; ... ... constructor TDerived.Create(AParam: TParamType); override The above code won't compile until I change the override keyword to "reintroduce". Because the compiler complains that there is no Create() with the same signature in the base class. Try to understand it on normal methods first. That is easier. (Technically it is the same for constructors, but you need a very abstract view, to realize this) TBase = class procedure Foo; virtual; ... TDerived = class procedure Foo; override; var b: TBase; d : TDerevied WITHOUT virtual/overide b := TDerived.Create b.Foo; // will ca Foo declared on TBAse (because "b" is declared as TBase) d.Foo // always call Foo from TDerived, because d can NOT contain a TBase anyway WITH virtual/overide b := TDerived.Create b.Foo; // will call Foo declared on TDerived (because "b" is CONTAINS a TDerived) ASSUMING (impossible) you wanted procedure Foo(a: String); override; b.Foo; // should call Foo declared on either TFoo or TDerived, depending what was assigned to b but if a TDerived was assigned, then it would break, because there is no argument. so this is impossible However, if I use reintroduce, according to the document, the compiler will make the Create method STATIC and hide the create method in the base class, in another word, it is then invalid to call TDerived.Create; (without param).What is the mechanism here?? Also, if I do not use override or reintroduce, instead, put an "overload" there, it will make BOTH version of the constructor visible, AND the "inherited" keyword also works well! "reintroduce" is just a way to get rid of the warning, indicating that you did not accidental use the same name as in the base class ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Understanding virtual methods
Thanks. Do you mean that the rules I see in the document apply to NORMAL virtual methods, but not virtual constructors? Also, I have a related question: it seems that to override methods in ancestor it is required that the method has same signature, however reintroduce will not have such limitations. Example: constructor TBase.Create; virtual; ... ... constructor TDerived.Create(AParam: TParamType); override The above code won't compile until I change the override keyword to "reintroduce". Because the compiler complains that there is no Create() with the same signature in the base class. However, if I use reintroduce, according to the document, the compiler will make the Create method STATIC and hide the create method in the base class, in another word, it is then invalid to call TDerived.Create; (without param).What is the mechanism here?? Also, if I do not use override or reintroduce, instead, put an "overload" there, it will make BOTH version of the constructor visible, AND the "inherited" keyword also works well! Could anyone explain these messes about: virtual, override, overload, reintroduce?? Thanks a lot. Shannon 2013/8/20 Martin > On 20/08/2013 02:44, Xiangrong Fang wrote: > > Hi All, > > I am reading this document: > http://www.freepascal.org/docs-html/ref/refsu29.html and doing an > experiment with the following code: > > program project1; > {$mode objfpc}{$H+} > type > TBase = class > constructor Create; virtual; > end; > TDerived = class(TBase) > constructor Create; override; > end; > > > > > The problem is, it makes NO DIFFERENCE at all in the following cases: > > CASE 1: > > TBase.Create; > TDerived.Create; > > CASE 2: > > TBase.Create; virtual; > TDerived.Create; virtual; > > CASE 3: > > TBase.Create; virtual; > TDerived.Create; override; > > According to the document, "inherited" cannot be used in non-virtual > methods, and it is wrong to use virtual in sub-class. But my test shows the > contrary. BTW, I am running Linux on 64bit platform. > > > > Using virtual with constructor makes a difference, if you use "class of" > types > > type > TBaseClass = class of TBase; > TDerivedClass = class of TDerived; > > Var > bc: TBaseClass; > > begin > bc:= TBase; > bc.create; > > bc:= TDerived; > bc.create; // will call Tderived.create, but only in case 3 > end; > > ___ > 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
Re: [fpc-pascal] Understanding virtual methods
On 20/08/2013 02:44, Xiangrong Fang wrote: Hi All, I am reading this document: http://www.freepascal.org/docs-html/ref/refsu29.html and doing an experiment with the following code: program project1; {$mode objfpc}{$H+} type TBase = class constructor Create; virtual; end; TDerived = class(TBase) constructor Create; override; end; The problem is, it makes NO DIFFERENCE at all in the following cases: CASE 1: TBase.Create; TDerived.Create; CASE 2: TBase.Create; virtual; TDerived.Create; virtual; CASE 3: TBase.Create; virtual; TDerived.Create; override; According to the document, "inherited" cannot be used in non-virtual methods, and it is wrong to use virtual in sub-class. But my test shows the contrary. BTW, I am running Linux on 64bit platform. Using virtual with constructor makes a difference, if you use "class of" types type TBaseClass = class of TBase; TDerivedClass = class of TDerived; Var bc: TBaseClass; begin bc:= TBase; bc.create; bc:= TDerived; bc.create; // will call Tderived.create, but only in case 3 end; ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Understanding virtual methods
Hi Flavio, Your findings confirmed mine, but not telling me why? It seems that the "virtual" keyword has no use at all! To confirm this, I just removed the "inherited" call in TDerived, then re-run the program with or without "virtual/override", the result is exactly same, i.e. with c2 (declared as TBase), the following statements ALWAYS calls constructor of TDerived, NOT TBase: c2 := TDerived.Create; c2 := TBase(TDerived.Create); This is not same as the description in: http://www.freepascal.org/docs-html/ref/refsu26.html BTW, the above documents are talking about objects, but I am using classes, is there any difference here? Shannon 2013/8/20 Flávio Etrusco > On Mon, Aug 19, 2013 at 10:44 PM, Xiangrong Fang wrote: > > Hi All, > > > > I am reading this document: > > http://www.freepascal.org/docs-html/ref/refsu29.html and doing an > > experiment with the following code: > > > > program project1; > > {$mode objfpc}{$H+} > > type > > TBase = class > > constructor Create; virtual; > > end; > > TDerived = class(TBase) > > constructor Create; override; > > end; > > > > var > > c1, c2: TBase; > > c3: TDerived; > > > > constructor TDerived.Create; > > begin > > WriteLn('Entering TDerived.Create'); > > inherited Create; > > WriteLn('Leaving TDerived.Create'); > > end; > > > > constructor TBase.Create; > > begin > > WriteLn('Entering TBase.Create'); > > Writeln('Leaving TBase.Create'); > > end; > > > > begin > > WriteLn('Creating a TBase and assigning to TBase variable...'); > > c1 := TBase.Create; > > WriteLn('Creating a TDerived and assigning to TBase variable...'); > > c2 := TDerived.Create; > > WriteLn('Creating a TDerived and assigning to TDerived variable...'); > > c3 := TDerived.Create; > > end. > > > > > > The problem is, it makes NO DIFFERENCE at all in the following cases: > > > > CASE 1: > > > > TBase.Create; > > TDerived.Create; > > > > CASE 2: > > > > TBase.Create; virtual; > > TDerived.Create; virtual; > > > > CASE 3: > > > > TBase.Create; virtual; > > TDerived.Create; override; > > > > According to the document, "inherited" cannot be used in non-virtual > > methods, > > At least that's the result I would expect :) > I can confirm your findings; contrary to the documentation, a simple > test works correctly (the compiler prints no warnings or hints, both > method and constructor work correctly, calling either a non-virtual > from virtual, and virtual from non-virtual). > > > > and it is wrong to use virtual in sub-class. > > It doesn't say that, it simply says that the redeclaration will not > override the base implementation (the different behavior for 'object' > is news to me!). > > FWIW your test doesn't actually "exercise" inheritance, since virtual > constructors only make a difference when you call from a class > reference (similarly, you'll only see a difference in virtual methods > when calling from a base-typed variable). > > Code>>> > var MyClass: TComponentClass = TDataModule; > begin > MyClass.Create(nil); > <<< > > will instantiate a TDataModule. > > Code>>> > var MyControl: TControl; > begin > MyControl := TButton.Create; > MyControl.ExecuteDefaultAction; > <<< > > will invoke TButton's implementation of ExecuteDefaultAction. > > > But my test shows the contrary. BTW, I am running Linux on 64bit > platform. > > > > Regards, > > Shannon > > Best regards, > Flávio > ___ > 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
Re: [fpc-pascal] Build Lazarus Ide - On "make bigide": lazaruspackageintf.pas(102, 1) Fatal: Internal error 2013081601
On Tue, Aug 20, 2013 at 1:54 AM, Osvaldo Filho wrote: > Anyone coud help-me? > > user1@movotcf:~/Documentos/Desenvolvimento/pascal/svn/ex/lazarus1010$ make > bigide > make -C packager/registration > make[1]: Entrando no diretório > `/home/user1/Documentos/Desenvolvimento/pascal/svn/ex/lazarus1010/packager/registration' > /bin/rm -f ../units/x86_64-linux/fcllaz.ppu > /usr/local/bin/ppcx64 -MObjFPC -Scghi -O1 -g -gl -vewnhi -l -Fu. > -Fu/usr/local/lib/fpc/2.7.1/units/x86_64-linux/rtl -FE. > -FU../units/x86_64-linux -Cg -dx86_64 fcllaz.pas > Hint: Start of reading config file /etc/fpc.cfg > Hint: End of reading config file /etc/fpc.cfg > Free Pascal Compiler version 2.7.1 [2013/08/19] for x86_64 > Copyright (c) 1993-2013 by Florian Klaempfl and others > Target OS: Linux for x86-64 > Compiling fcllaz.pas > Compiling registerfcl.pas > Compiling lazaruspackageintf.pas > lazaruspackageintf.pas(102,1) Fatal: Internal error 2013081601 > Fatal: Compilation aborted > make[1]: ** [fcllaz.ppu] Erro 1 > make[1]: Saindo do diretório > `/home/user1/Documentos/Desenvolvimento/pascal/svn/ex/lazarus1010/packager/registration' > make: ** [registration] Erro 2 > (...) >From the git log, revision 25266 introduced a check that forces this error. -Flávio ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Build Lazarus Ide - On "make bigide": lazaruspackageintf.pas(102, 1) Fatal: Internal error 2013081601
Anyone coud help-me? user1@movotcf:~/Documentos/Desenvolvimento/pascal/svn/ex/lazarus1010$ make bigide make -C packager/registration make[1]: Entrando no diretório `/home/user1/Documentos/Desenvolvimento/pascal/svn/ex/lazarus1010/packager/registration' /bin/rm -f ../units/x86_64-linux/fcllaz.ppu /usr/local/bin/ppcx64 -MObjFPC -Scghi -O1 -g -gl -vewnhi -l -Fu. -Fu/usr/local/lib/fpc/2.7.1/units/x86_64-linux/rtl -FE. -FU../units/x86_64-linux -Cg -dx86_64 fcllaz.pas Hint: Start of reading config file /etc/fpc.cfg Hint: End of reading config file /etc/fpc.cfg Free Pascal Compiler version 2.7.1 [2013/08/19] for x86_64 Copyright (c) 1993-2013 by Florian Klaempfl and others Target OS: Linux for x86-64 Compiling fcllaz.pas Compiling registerfcl.pas Compiling lazaruspackageintf.pas *lazaruspackageintf.pas(102,1) Fatal: Internal error 2013081601* Fatal: Compilation aborted make[1]: ** [fcllaz.ppu] Erro 1 make[1]: Saindo do diretório `/home/user1/Documentos/Desenvolvimento/pascal/svn/ex/lazarus1010/packager/registration' make: ** [registration] Erro 2 I do not understand this error. This version of lazarus and Trunk show this error. My environment: Ubuntu 13.04 Amd64 FPC 2.7.1 rev: 25295 My /etc/fpc.cfg: -O2 -Xs -gl -Crtoi -ap -FD/Applications/Xcode.app/Contents/Developer/usr/bin -Sgic -Cppentiumm -Oppentiumm -Fu/usr/local/lib/fpc/$fpcversion/units/$fpctarget -Fu/usr/local/lib/fpc/$fpcversion/units/$fpctarget/* -Fu/usr/local/lib/fpc/$fpcversion/units/$fpctarget/rtl -Fu/usr/local/lib/fpc/$fpcversion/units/$fpctarget/httpd13/ -Fu/usr/local/lib/fpc/$fpcversion/units/$fpctarget/httpd20 -Fu/usr/local/lib/fpc/$fpcversion/units/$fpctarget/httpd22 -Fu~/.fppkg/lib/fpc/$fpcversion/units/$FPCTARGET/* -Fl/usr/lib/gcc/x86_64-linux-gnu/4.7 -Fl/usr/lib/gcc/x86_64-linux-gnu/4.7 -Fl/usr/local/lib/fpc/$fpcversion/lib/$FPCTARGET -FD/usr/local/lib/fpc/$fpcversion/bin/$FPCTARGET -XP$FPCTARGET- -Xs -l -viwn Modify message ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Understanding virtual methods
On Mon, Aug 19, 2013 at 10:44 PM, Xiangrong Fang wrote: > Hi All, > > I am reading this document: > http://www.freepascal.org/docs-html/ref/refsu29.html and doing an > experiment with the following code: > > program project1; > {$mode objfpc}{$H+} > type > TBase = class > constructor Create; virtual; > end; > TDerived = class(TBase) > constructor Create; override; > end; > > var > c1, c2: TBase; > c3: TDerived; > > constructor TDerived.Create; > begin > WriteLn('Entering TDerived.Create'); > inherited Create; > WriteLn('Leaving TDerived.Create'); > end; > > constructor TBase.Create; > begin > WriteLn('Entering TBase.Create'); > Writeln('Leaving TBase.Create'); > end; > > begin > WriteLn('Creating a TBase and assigning to TBase variable...'); > c1 := TBase.Create; > WriteLn('Creating a TDerived and assigning to TBase variable...'); > c2 := TDerived.Create; > WriteLn('Creating a TDerived and assigning to TDerived variable...'); > c3 := TDerived.Create; > end. > > > The problem is, it makes NO DIFFERENCE at all in the following cases: > > CASE 1: > > TBase.Create; > TDerived.Create; > > CASE 2: > > TBase.Create; virtual; > TDerived.Create; virtual; > > CASE 3: > > TBase.Create; virtual; > TDerived.Create; override; > > According to the document, "inherited" cannot be used in non-virtual > methods, At least that's the result I would expect :) I can confirm your findings; contrary to the documentation, a simple test works correctly (the compiler prints no warnings or hints, both method and constructor work correctly, calling either a non-virtual from virtual, and virtual from non-virtual). > and it is wrong to use virtual in sub-class. It doesn't say that, it simply says that the redeclaration will not override the base implementation (the different behavior for 'object' is news to me!). FWIW your test doesn't actually "exercise" inheritance, since virtual constructors only make a difference when you call from a class reference (similarly, you'll only see a difference in virtual methods when calling from a base-typed variable). Code>>> var MyClass: TComponentClass = TDataModule; begin MyClass.Create(nil); <<< will instantiate a TDataModule. Code>>> var MyControl: TControl; begin MyControl := TButton.Create; MyControl.ExecuteDefaultAction; <<< will invoke TButton's implementation of ExecuteDefaultAction. > But my test shows the contrary. BTW, I am running Linux on 64bit platform. > > Regards, > Shannon Best regards, Flávio ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Understanding virtual methods
Hi All, I am reading this document: http://www.freepascal.org/docs-html/ref/refsu29.html and doing an experiment with the following code: program project1; {$mode objfpc}{$H+} type TBase = class constructor Create; virtual; end; TDerived = class(TBase) constructor Create; override; end; var c1, c2: TBase; c3: TDerived; constructor TDerived.Create; begin WriteLn('Entering TDerived.Create'); inherited Create; WriteLn('Leaving TDerived.Create'); end; constructor TBase.Create; begin WriteLn('Entering TBase.Create'); Writeln('Leaving TBase.Create'); end; begin WriteLn('Creating a TBase and assigning to TBase variable...'); c1 := TBase.Create; WriteLn('Creating a TDerived and assigning to TBase variable...'); c2 := TDerived.Create; WriteLn('Creating a TDerived and assigning to TDerived variable...'); c3 := TDerived.Create; end. The problem is, it makes NO DIFFERENCE at all in the following cases: CASE 1: TBase.Create; TDerived.Create; CASE 2: TBase.Create; virtual; TDerived.Create; virtual; CASE 3: TBase.Create; virtual; TDerived.Create; override; According to the document, "inherited" cannot be used in non-virtual methods, and it is wrong to use virtual in sub-class. But my test shows the contrary. BTW, I am running Linux on 64bit platform. Regards, Shannon ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal