Given the following class hierarchy:
TClass1 = class
end;
TClass2a = class(TClass1)
end;
TClass2b = class(TClass1)
end;
I operate on them using the following overloaded procedures
procedure DoSomething(AObj : TClass1); overload;
begin
// ...Do something for TClass1
end
procedure DoSomething(AObj : TClass2a); overload;
begin
// Do something as parent class
DoSomething(TClass1(AObj))
// ...Do something for TClass2a
end
procedure DoSomething(AObj : TClass2b); overload;
begin
// Do something as parent class
DoSomething(TClass1(AObj))
// ...Do something for TClass2b
end
How can I dynamically cast each parameter to its parent class, instead of hard coding it?
I’d like to replace this:
// Do something as parent class
DoSomething(TClass1(AObj))
With something more generic, like this
// Do something as parent class
DoSomething(AObj.ClassParent(AObj))
Update: DoSomething procedures must reside outside the class hierarchy in this case. I can’t reverse the structure, so I can’t take advantage of class inheritance and polymorphism.
Furthermore, this is just an example. I’d like answers to focus on the core question: how can I cast an object to its parent class at runtime.
overloadis only useful at compile-time, it allows the compiler to select the most appropriate method based on the type of the object that’s passed as a parameter. You can’t use theoverloadmechanism at run time to dynamically make the call because, by that time, the code has been compiled and the one overloaded procedure already chosen. For all you know the proper method to call (based on “overloaded” logic) might not even be available: If the compiler never chose the overloaded method for anything, the linker might have discarded. Because of this you can’t use RTTI, because the method might simply NOT EXIST in the executable, unless you already hard-coded a call to it.Your only choice is to do some hard coding. I’d create a method that takes two parameters, the object to operate on and a
TClassparameter, something like this:Given an object of type
TClass3, this procedure will callDoSomething3 times, once for each level of inheritance. And it will choose the proper overloaded version because of the hard-coded cast.Sample code:
Since the code doesn’t really use the
overloadedkeyword for anything useful, I’d drop it’s use, give distinct names to all methods so the code in the Dispatcher method looks like this:This variant is safer in the long-run because it doesn’t depend on compiler-magic. For example, in the first variant, if you decide to drop the overloaded procedure that works for a parameter of type
TClass2but you’d forget to drop the call with theTClass2()cast in the Dispatcher, you’d get two calls for the overloaded method that takes theTClass1parameter, because that would be the best match for the now useles: