Sign in Join

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

Mailing lists / lazarus / 2013-04

Different "default" value for a property in derived class

9 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

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

Bart

Hi,

Consider this.

type
  TSomeType = (stA, stB, stC);
  { TA }
  TA = class
  private
    FFoo: TSomeType;
  public
    constructor Create;  virtual;
  published
    property Foo: TSomeType read FFoo write FFoo default stA;
  end;
  { TB }
  TB = class(TA)
  public
    constructor Create; override;
  end;
implementation

{ TB }

constructor TB.Create;
begin
  inherited Create;
  Foo := stB;
end;

{ TA }

constructor TA.Create;
begin
  FFoo := stA;
end;

Now imagine that you drop an instance ot TB on a form. In OI you set Foo to stA.

You build and run, and to your surprise Foo is stB. You think for a while and realize what happened: since property TA.Foo is declared with "default stA", this means that if you set Foo in OI to stA it is not streamed to the LFM.

So far, so good.

Now the question: is there any other way to fix this besides removing the "default stA' from the declaration of the TA.Foo property? (Assuming that it is necessary for TB to set Foo to stB by default).

Bart

Reply by email

Michael Van Canneyt
to Bart
Bart wrote 56 lines
Hi, Consider this. type TSomeType = (stA, stB, stC); { TA } TA = class private FFoo: TSomeType; public constructor Create; virtual; published property Foo: TSomeType read FFoo write FFoo default stA; end; { TB } TB = class(TA) public constructor Create; override; end; implementation { TB } constructor TB.Create; begin inherited Create; Foo := stB; end; { TA } constructor TA.Create; begin FFoo := stA; end; Now imagine that you drop an instance ot TB on a form. In OI you set Foo to stA. You build and run, and to your surprise Foo is stB. You think for a while and realize what happened: since property TA.Foo is declared with "default stA", this means that if you set Foo in OI to stA it is not streamed to the LFM. So far, so good. Now the question: is there any other way to fix this besides removing the "default stA' from the declaration of the TA.Foo property? (Assuming that it is necessary for TB to set Foo to stB by default).

Just change the default:

   TB = class(TA)
   public
     constructor Create; override;
   published
     property foo default stB;
   end;

Michael.

Reply by email

Jether yahoo
to Bart

This doesn't make any sense to me, TB is descendent of TA, TB should never affect the behavior of it's ancestror TA.

Jether Fernandes Reis
-----Mensagem Original-----
De: "Bart"
Para: "Lazarus mailing list"
Enviada em: s?bado, 6 de abril de 2013 11:52
Assunto: Re: [Lazarus] Different "default" value for a property in derivedclass

Show quoted text 22 lines
On 4/6/13, Michael Van Canneyt wrote: > Just change the default: > > TB = class(TA) .... > property foo default stB; > end; > Yes, that did it. I tried something like that, but didn't get the syntax right. Thanks a lot. Bart -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Hans-Peter Diettrich
to Jether yahoo
This doesn't make any sense to me, TB is descendent of TA, TB should never affect the behavior of it's ancestror TA.

Properties are evaluated at compile time. When an object reference is known to be of type TB, the compiler uses the getter/setter methods of TB.

Nonetheless I don't understand what initialized properties in non-component classes are good for, together with the observed behaviour of default values. Can somebody point me to the according documentation?

DoDi

Reply by email

Sven Barth
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote
Nonetheless I don't understand what initialized properties in non-component classes are good for, together with the observed behaviour of default values. Can somebody point me to the according documentation?

Streaming is introduced with TPersistent (or to be more precise: with any class declared when $M+ is set), so one can use this for streaming ones own classes or to build a different GUI toolkit (e.g. in theory Graeme could use the streaming for fpGUI as well).

Regards,
Sven

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich: Properties are evaluated at compile time. When an object reference is known to be of type…
Hans-Peter Diettrich wrote 10 lines
Jether (yahoo) schrieb: > This doesn't make any sense to me, TB is descendent of TA, TB should never > affect the behavior of it's ancestror TA. Properties are evaluated at compile time. When an object reference is known to be of type TB, the compiler uses the getter/setter methods of TB. Nonetheless I don't understand what initialized properties in non-component classes are good for, together with the observed behaviour of default values. Can somebody point me to the according documentation?

Default values are simply stored in RTTI.
RTTI is generated for all TPersistence descendents such as TStrings or TCollectionItem. (or as Sven pointed out, any descendent of a class compiled in {$M+})

They have no other purpose than inform a streaming implementation what the default value is expected to be after the constructor was called.

There is no guarantee from the compiler that this will actually be the case. It depends on the constructor of the class.

This can be used to:

* omit values when streaming the component. This is what is currently done.

* One could imagine an implementation in a class that retrieves all default values and initializes them "automatically". However, this can have side-effects if there is a property setter, so it is not implemented in TComponent.

All this is documented in the language reference manual:

http://www.freepascal.org/docs-html/ref/refsu37.html

Michael.

Reply by email

Graeme Geldenhuys
to Jether yahoo: This doesn't make any sense to me, TB is descendent of TA, TB should never affect the…
Jether wrote
This doesn't make any sense to me, TB is descendent of TA, TB should never affect the behavior of it's ancestror TA.

TB doesn't affect the behaviour of TA. TB extends or descends from TA, altering its own behaviour. That is the purpose of descendants - add or change functionality. Because TB changed the default value in the constructor, it should also notify the RTTI system about that change, hence the redeclared property with a new 'default stB' text.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Graeme Geldenhuys
to Sven Barth: Streaming is introduced with TPersistent (or to be more precise: with any class declared…

Hi Hans-Peter,

Sven Barth wrote
ones own classes or to build a different GUI toolkit (e.g. in theory Graeme could use the streaming for fpGUI as well).

I consciously decided not to use streaming in fpGUI (but in theory I could have, yes). I do use RTTI in the fpGUI Forms Designer though, to reduce the amount of Object Pascal code the form designer generates. eg: For RTTI to work, properties must be Published. I then check those properties, and see if they are equal to their default values, in which case I don't generate Object Pascal code.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email