I am having problems calling the Create () virtual method incorrectly while creating a dynamic object. The parent method is called, not the decendant method.
I looked through these posts but cannot figure it out:
Delphi - create a class from a string
Learning TRTTIType and Descendants
Can I pass a class type as a procedure parameter
and here Class_References
I have the following classes:
TCellObj = class(TPhysicsObj) ... public constructor Create(RgnMgr : TObject); virtual; //RgnMgr should be TRgnManager destructor Destroy; ... end; TCellObjClass = Class of TCellObj; -------------------------------- TCellTrialAObj = class(TCellObj) ... public ... constructor Create(RgnMgr : TObject); virtual; //RgnMgr should be TRgnManager end; -------------------------------- TRgnManager = class (TObject) ... public function NewCell(ClassRef : TCellObjClass) : TCellObj; ... end; .... function TRgnManager.NewCell(ClassRef : TCellObjClass) : TCellObj; var CellObj : TCellObj; begin CellObj := ClassRef.Create(Self); CellObj.DefaultInitialize; CellObj.Color := TAlphaColors.Slategray; FCellsList.Add(CellObj); //This will own objects. SetSelection(CellObj); Result := CellObj; end;
And finally, I begin the process of creating a dynamic object on the following line:
RgnManager.NewCell(TCellTrialAObj);
My goal is for TRgnManager.NewCell to create any decendant from TCellObj based on the derived class passed as a parameter. I will be wrapping the result to the appropriate class type during use.
When I view the code using the debugger in NewCell, the Evaluate / Modify tool tells me that ClassRef = TCellTrialAObj, as expected.
But when I enter the ClassRef.Create (self) line, it goes to TCellObj .Create (), and not to TCellTrialAObj.Create (), as I expected. This is the part that I do not understand.
After the result has been assigned to CellObj, the Evaluate / Modify tool tells me that CellObj.ClassName = 'TCellTrialAObj';
So, ClassRef was from TCellTrialAObj, then why the Create () function did not call TCellTrialAObj.Create () ??
Thanks in advance.
PS I am using Embarcadero® Delphi 10 Seattle Version 23.0.22248.5795
ADDITION
I combined this function below using examples from the links above. It seems to work, and calls TCellTrialAObj.Create as desired. But I don’t understand how, why, or if I really do it right. Can someone explain?
function TRgnManager.NewCell(ClassRef : TCellObjClass) : TCellObj; var CellObj : TCellObj; RT : TRttiType; C : TRttiContext; T : TRttiInstanceType; V : TValue; begin C := TRttiContext.Create; T := (C.GetType(ClassRef) as TRttiInstanceType); V := T.GetMethod('Create').Invoke(T.metaClassType,[self]); C.Free; CellObj := V.AsObject as TCellObj;