Why am I able to access UE4 class's private members?

The GENERATED_UCLASS_BODY() macro inserts a ‘public:’ at the end, so everything afterwards has indeed public scope. I know, it’s unexpected, but that’s how things have been pretty much forever.

When following along with the tanks vs. zombies tutorial from unreal there is section where the programmer creates a spring arm component in the tank’s constructor like so

ATank::ATank()
{
    USpringArmComponent* springArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Spring Arm"));
}

and then he goes on accessing that SpringArm’s variables and setting default values for them:

ATank::ATank()
{
    USpringArmComponent* SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Spring Arm"));
    SpringArm->CameraLagSpeed = 2.0f;
    SpringArm->TargetArmLength = 300.f;
}

The problem is those variables - CameraLagSpeed, TargetArmLength - and others are actually private in the USpringArmComponent class in UE4:

UCLASS(ClassGroup=Camera, meta=(BlueprintSpawnableComponent), hideCategories=(Mobility))
class ENGINE_API USpringArmComponent : public USceneComponent
{
	GENERATED_UCLASS_BODY()

	/** Natural length of the spring arm when there are no collisions */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Camera)
	float TargetArmLength;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Lag, meta=(editcondition="bEnableCameraLag",   ClampMin="0.0", ClampMax="1000.0", UIMin = "0.0", UIMax = "1000.0"))
	float CameraLagSpeed;

       etc..........
}

Since in C++ the default access specifier (public, private, protected) is private when you don’t specifiy it yourself. So why are you able to access SpringArm’s variables? Does UE4’s classes actually default to the public specifier instead of private?

Hi,

GENERATED_UCLASS_BODY() expands out to some code which includes a public: specifier. This is a deprecated macro, and if it was replaced with the new GENERATED_BODY(), which preserves access, then you’d get the expected errors when trying to access the private variables.

These macro replacements will likely happen over time, but USpringArmComponent hasn’t yet been switched.

Hope this clears it up,

Steve

Ohhh, okay. That clears things up perfectly. Thank you for the response.

Ya that seems odd to me and potentially dangerous.

FWIW, GENERATED_BODY doesn’t do this. This is the version that we recommend people use in new code.

And I see now that Steve already mentioned that. Doh!

haha funny.