There is this weird interaction I’ve been encountering lately, Where if I reinterpret cast a parent of class which inherits a UINTERFACE and then call something on it I get an access violation error. For example:
UCLASS()
class AMyActor : public AActor, Public IMyInterface {...}
SomeMethod()
{
AActor* MyActorInstance = GetMyActorFromSomeWhere();
IMyInterface* MyInterfaceInstace = reinterpret_cast<IMyInterface*>(MyActorInstance);
MyInterfaceInstace->DoSomething();
}
This gives an error. While if I use normal Cast instead it works. I have checked the Cast code and it’s basically just a c style cast. How does that work while reinterpret_cast does not?
the UE Cast<T> is a template function that includes type checking and error handling before the conversion is done.
it has a knowledge of UObject and everything that inherits from UObject in your project, and checks the hierarchy first
can NOT be used for things that DON"T derive from UObject
can be slower at times because it does checks and error handling
while the c/c++ cast<T> (and and other variants including reinterpret_cast) is an operator built to conform to the c/c++ standard, that will forcibly try to do the conversion first then live with the consequences.
it only knows whether or not the T is a object type, and tries the conversion “trusting” the programmer
is rather fast for integral types, but slows down and can cause issues for complex types.
can cause “undefined behavior” (a crash can be the “best” result) if the conversion is not valid
for example in c/c++ you can do
//this is valid, but rarely ever useful unless you are purposely doing "pointer magic"
int* ptr = reinterpret_cast<int*>(somePointer);
if you are using a UObject derived class to a UObject derived class then use UE Cast<T>
and for your example shouldn’t this be dynamic_cast<IMyInterface*> because the interface is typically trying to access thing on the Virtual Function Table?
Compiler cannot jump from AActor to IMyInterface, you need to cast to AMyActor inbetween.
Internally, UE is a bit more complex than that. The cast implementation from object to interface uses the reflection system to look up object’s implemented interfaces (stored in the UClass). It accesses the UClass via GetClass() which is polymorphic, so even with your variable of type AActor* it returns the UClass of AMyActor. The UClass contains information about your interface, including its virtual table offset within AMyActor class. Then it can jump to that offset with a c-style cast.