General Knowledge Question on Coding Structure for C++

I’ve gone through a couple courses on C++ and Unreal and am curious on how a developer determines where to define their variables.
Besides creating local variables within functions for the .cpp file, if you declare a variable in the header file, what helps you determine where the variable should be defined?
So far, I’ve gathered that variable definition in a class constructor is good for constructing objects, like creating components and assigning their root component. But technically you could do this in BeginPlay() as well because the function is only called once. So what is a good coding style to follow if I’m trying to get into this stuff for a hobby? If it comes down to personal preference, what do you personally do?

-Thanks!

Class Member Variables

Variables defined as class members as follows

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT_API UMyComponent : public USceneComponent

protected:
	void BeginPlay() override;
	void OnUnregister() override;
	void OnRegister() override;

private:
	FTimerHandle fth;
	class AStaticMeshActor* Parent;		
};

can be used in more than one member functions:

void UMyComponent::OnUnregister()
{
	Super::OnUnregister();
	if (Parent)
		Parent->GetWorldTimerManager().ClearTimer(fth);
}

void UMyComponent::OnRegister()
{
	Super::OnRegister();
	Parent = Cast<AStaticMeshActor>(GetOwner());
}

In other words, variables defined as class members have class scope.

Another example:

You have a character that can fire a weapon. If you press and hold a key, the character fires, but if you release the key, the character stops firing. How to do this? You need to define a shared variable called IsPressed of type bool as a class member variable.
You have 3 functions: OnPress(), OnRelease() and Tick().

  • set IsPressed = true; in OnPress(),
  • set IsPressed = false; in OnRelease() and
  • use if(IsPressed){//fire} else {//stop firing} in Tick().

Of course you can share this IsPressed as a global scope variable but it is not good practice!

Local Variables

The following variable T has a local scope which is in BeginPlay() only. You cannot call T from other functions.

void USpawningBallComponent::BeginPlay()
{
	Super::BeginPlay();
	FTransform T = Parent->GetTransform();
}

The best candidate of local variables are ones that

  • you don’t want to share with other parts of your code and
  • are temporarily needed.

Global Variables

We can also define variables with global scope as follows but it is considered as a bad practice. The variables can be called from many places.

#include "Something.h"
uint32 TheNumberOfInstance = 1000;
float Pi = 3.1415926535897932;
// etc