Documentation / Syntax question

Hi everyone,

I completed the challenge successfully with this line of code:

FString ObjectPosition = GetOwner()->AActor::GetActorLocation().FVector::ToString();

There’s a bit in there that Mike didn’t include in his code, though it returned the same result. I added the AActor:: and FVector:: portions because that’s what I saw in the documentation here. Were those not required because the objects that were being operated on were an AActor and FVector, respectively, and the IDE/compiler used that context to figure out what fucntion to call? How could I tell in the future whether I need to call a function with that level of specificity? Would the code just fail to compile if I tried running GetActorLocation on an object that wasn’t an AActor?

I also added

#include "Math/Vector.h"

to the cpp as it was listed as an include on the doc page for FVector::ToString, but again, Mike didn’t do that and his code worked the same. What’s the best way to check to see if something is already included in another header, as it must be in this case?


Its possible to rely on the IDE for suggestions as at times that does improve code but other times its a funny thing and sometimes can be flat out wrong because of bugs with the IDE feature.

There’s a lot of possibilities that I would refrain from suggesting what must be. Obviously if the end result is correct all the time, it works. Does it mean its worse or better? That requires…

It to be looked at with different glasses so-to-speak. Someone looking to lower the amount of calls will look at it one way. Someone who is trying to get something workable as quickly as possible will another way, deprecation, the elusive so-called “correctness”, some people feel like some code is too hacky, making sure it will work 100% of the time, etc.

You may need to look at it in all those ways and more. Some people will, some won’t.

If you call it once, it won’t matter much. If you call it 100,000 times (or heavily) you might want to time their way and your way, etc. as there could be a big difference. If you want to spend forever on every piece of code, that can be done also.

If you quickly see that you can drop the amount of calls made and still be working correctly, that is generally going to be better.

You can kind of get the idea that it all depends with every single piece of code you write? It eats as much time as you want :slight_smile:

Not claiming to be an expert but this is what I’ve learnt so far that I think is correct.

You can’t guarantee GetOwner() won’t return null as it depends on when everything gets created, I already got caught out with that one :slight_smile: so need to check it’s not null first. also you can just call .ToString() reads easier.

	AActor* Owner = GetOwner();
	if (Owner)
		FString ObjectPosition = Owner->GetActorLocation().ToString();
		UE_LOG(LogTemp, Warning, TEXT("Owner Position %s"), *ObjectPosition);

including Math/Vector.h is not related that’s the c++ vector this is using FVector which is unreals implementation, my understanding is use the unreal implementations unless you really know what to expect as Unreal has implemented various garbage collection strategies that happen behind the scenes and you might find native c objects are not around as you might expect. Take that include out and try recompiling, unless you have used Vector somewhere else instead of FVector it should be fine.

Try calling GetActorLocation on something that’s not an actor what’s the worst that can happen, it will just fail to build and it’s good to see the error messages. If it’s a subclass of AActor it will most likely work or if it’s implemented it’s own GetActorLocation it will work.

happy to be corrected as always but that’s my understanding.

That’s because that’s where those are defined. Without it then it would be defining a global non-member function.

#include <iostream>

class Example
    void Foo();
void Example::Foo() { std::cout << "Example::Foo() called\n"; }
void Foo() { std::cout << "Foo() called\n"; }

int main()
    Example E;
    E.Foo(); // Example::Foo() called
    Foo();  // Foo() called