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 <flavio.etru...@gmail.com> > On Mon, Aug 19, 2013 at 10:44 PM, Xiangrong Fang <xrf...@gmail.com> 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