Create constructor never called in the TRVGraphicItemInfo descendants

General TRichView support forum. Please post your questions here
Post Reply
Vitalii
Posts: 69
Joined: Sat Oct 20, 2018 2:55 pm

Create constructor never called in the TRVGraphicItemInfo descendants

Post by Vitalii »

I have the following problem. I am creating a descendant of TRVGraphicItemInfo using CreateEx constructor, but the overridden Create constructor is never called. As a result, I cannot initialize additional properties:

Code: Select all

TRVChartItemInfo = class(TRVGraphicItemInfo);

constructor TRVChartItemInfo.Create(ARVData: TPersistent);
begin
  inherited Create(ARVData);
  StyleNo := rvsChartObject;  // <-- this code never executed!
end;

{ ... create instance ... }

class function TRVChartItemInfo.InsertTo(RVData: TCustomRVData; ChartData: TStrings): TRVChartItemInfo;
begin
  Result := TRVChartItemInfo.CreateEx(RVData, TBitmap.Create(500, 400), TRVVAlign.rvvaBaseline);
  { .. }
end;

Perhaps “inherited” is not needed in the TRVGraphicItemInfo.CreateEx constructor? Please check.
Sergey Tkachenko
Site Admin
Posts: 18010
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Create constructor never called in the TRVGraphicItemInfo descendants

Post by Sergey Tkachenko »

AFAIK, virtual constructors do not work in the way you expect.
Yes, TRVGraphicItemInfo.CreateEx calls inherited Create(ARVData), i.e. constructor TRVRectItemInfo.Create(ARVData: TPersistent), which is virtual.
However, even if you override this constructor in your class, TRVGraphicItemInfo.CreateEx will call TRVRectItemInfo.Create: virtuality does not allow to replace the constructor here.

But even if this worked as you expect, it wouldn't have any effect. TRVGraphicItemInfo.CreateEx changes StyleNo after calling inherited Create, so your value would still be lost.

Solution: overwrite both Create and CreateEx constructors.
Vitalii
Posts: 69
Joined: Sat Oct 20, 2018 2:55 pm

Re: Create constructor never called in the TRVGraphicItemInfo descendants

Post by Vitalii »

Yes, I am currently overriding both constructors. This issue is more about expected behavior: the Create constructor is usually interpreted as the main one, responsible for initializing all fields. All other constructors are interpreted as secondary (CreateEx). In my opinion, it would be logical to call Create without inherited in CreateEx — then there would be no need to rewrite both constructors. But this is just a recommendation :)
Post Reply