# Public, protected or private with AllowPrivateAccess - Best practices

**URL:** <https://forums.unrealengine.com/t/public-protected-or-private-with-allowprivateaccess-best-practices/578689>\
**Category:** C++\
**Tags:** unreal-engine, UE5-0, Code, question\
**Created:** [June 10, 2022, 1:22pm UTC](https://forums.unrealengine.com/t/public-protected-or-private-with-allowprivateaccess-best-practices/578689 "2022-06-10T13:22:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![DevKaiUnreal](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/devkaiunreal/32/935713_2.png) [@DevKaiUnreal](https://forums.unrealengine.com/u/DevKaiUnreal)\
**Post date:** [June 10, 2022, 1:22pm UTC](https://forums.unrealengine.com/t/public-protected-or-private-with-allowprivateaccess-best-practices/578689/1 "2022-06-10T13:22:07Z")

</div>

Hi,

I know the meaning of these access modifiers and the concept of encapsulation. My general rule of thumb (also outside of Unreal) is to mark as…

- `private`: As much as possible
- `protected`: if it’s necessary to expose members of the base class to a child class
- `public`: only getters/setters and the public interface

Therefore I make heavy use of `meta=(AllowPrivateAccess = true)`. Is this a code smell? Are the any best practices?

Thanks for any hints!

---

<div class="post-metadata">

**Author:** ![anonymous\_user\_4aa5607e1](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@anonymous\_user\_4aa5607e1](https://forums.unrealengine.com/u/anonymous_user_4aa5607e1)\
**Post date:** [June 13, 2022, 11:12am UTC](https://forums.unrealengine.com/t/public-protected-or-private-with-allowprivateaccess-best-practices/578689/2 "2022-06-13T11:12:10Z")

</div>

Seems a bit strange to me to routinely have stuff that’s inaccessible in C++ be accessible via BP?

---

<div class="post-metadata">

**Author:** ![DevKaiUnreal](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/devkaiunreal/32/935713_2.png) [@DevKaiUnreal](https://forums.unrealengine.com/u/DevKaiUnreal)\
**Post date:** [June 14, 2022, 12:21pm UTC](https://forums.unrealengine.com/t/public-protected-or-private-with-allowprivateaccess-best-practices/578689/3 "2022-06-14T12:21:43Z")

</div>

> Seems a bit strange to me to routinely have stuff that’s inaccessible in C++ be accessible via BP?

Exactly. Actually there is a third option **BlueprintGetter** as discussed in a related thread [https://forums.unrealengine.com/t/why-are-blueprintgetter-not-visible/579329](https://forums.unrealengine.com/t/why-are-blueprintgetter-not-visible/579329).

What I usually see in tutorals is the **AllowPrivateAccess** option. However, to me this seems more like a workaround. Shouldn’t be made more heavy use of **BlueprintGetter** and **BlueprintSetter**? What is the best coding practice?

---

<div class="post-metadata">

**Author:** ![JoSf](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@JoSf](https://forums.unrealengine.com/u/JoSf)\
**Post date:** [June 14, 2022, 7:29pm UTC](https://forums.unrealengine.com/t/public-protected-or-private-with-allowprivateaccess-best-practices/578689/4 "2022-06-14T19:29:05Z")

</div>

Only use getters if your getter needs to do some special checks or other procedures when getting the variable, or to protect the variable from being set.

Only use setters if you need to do special checks etc. when the variable is being set.

(That or the variable is accessed via an interface for which you need functions)

If you have a variable that needs to be accessed by other classes and there are no special checks or other things the class needs to do before allowing the other classes to modify / read the variable, just leave it public.

Don’t bloat the header files that is not needed. Doing encapsulation for the sake of encapsulation is a fool’s errand and you end up with more code, not less. Having public variable communicates more on its own than with getters and setters, it tells the programmer that no special checks are needed whatsoever. Encapsulation should not be used to make every class completely independent from each other by default. Sometimes a bunch of classes are needed together to form a set of functionality. If class A and class B are always going to be a present when the system they form is being used, then the connection may just as well be explicit. Only when different classes need to interact with each other but aren’t always necessarily present at the same time, you want to set up some sort of interface to carry that information.

BlueprintGetter / BlueprintSetter only allows you to add a special check before the variable is taken in the blueprint graph. If you need some specialized function to handle variables you could also make a custom getter as an UFUNCTION() and set is as BlueprintCallable. That way you could also do errorhandling, just like how the casting nodes have another execution output in case the cast fails.

I recommend reading on some of the source classes like ACharacter to see how their header files have been setup.

---

<div class="post-metadata">

**Author:** ![DevKaiUnreal](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/devkaiunreal/32/935713_2.png) [@DevKaiUnreal](https://forums.unrealengine.com/u/DevKaiUnreal)\
**Post date:** [June 15, 2022, 5:52pm UTC](https://forums.unrealengine.com/t/public-protected-or-private-with-allowprivateaccess-best-practices/578689/5 "2022-06-15T17:52:33Z")

</div>

Thanks for the comprehensive answer! I also liked how’d you describe the BlueprintGetters/Setters as overrides in the beforementioned thread. I have the impression, that even though encapsulation concepts are quite the same among programming languages, they are still anticipated a bit differently (in C# people tend to encapsulate everything).

In Unreal it seems there is little hesitation in making properties public, if there is no additional access logic or need to hide it. I took a look into the `ACharacter` class (UE5.01). Just to get a feeling for it.

`ACharacter`:

- Total number of lines of code for the class: 782
- private: 19
- protected: 56
- public: 705

The 19 LoC for the private section are spend solely on `USceneComponent`s and `BlueprintReadOnly`:

```auto
private:
	/** The main skeletal mesh associated with this Character (optional sub-object). */
	UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
	TObjectPtr<USkeletalMeshComponent> Mesh;

	/** Movement component used for movement logic in various movement modes (walking, falling, etc), containing relevant settings and functions to control movement. */
	UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
	TObjectPtr<UCharacterMovementComponent> CharacterMovement;

	/** The CapsuleComponent being used for movement collision (by CharacterMovement). Always treated as being vertically aligned in simple collision check functions. */
	UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
	TObjectPtr<UCapsuleComponent> CapsuleComponent;

#if WITH_EDITORONLY_DATA
	/** Component shown in the editor only to indicate character facing */
	UPROPERTY()
	TObjectPtr<UArrowComponent> ArrowComponent;
#endif

```

Just for the information. Thanks, and bye!

---

<div class="post-metadata">

**Author:** ![DevKaiUnreal](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/devkaiunreal/32/935713_2.png) [@DevKaiUnreal](https://forums.unrealengine.com/u/DevKaiUnreal)\
**Post date:** [December 15, 2022, 1:35pm UTC](https://forums.unrealengine.com/t/public-protected-or-private-with-allowprivateaccess-best-practices/578689/6 "2022-12-15T13:35:55Z")

</div>

What I found in the offical and comprehensive C++ **LyraStarterGame** predominantly…

**public:**

- No variables, only functions with `UFUNCTION(BlueprintCallable or BlueprintPure)`
- Or delegates with `UPROPERTY(BlueprintAssignable)`

**protected:**

- Often blank because Macros are inherited
- Almost no variables only functions

**private:**

- Components are always:  
`UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Meta = (AllowPrivateAccess = "true"))`
- Variables are often `UPROPERTY()`
- Exposed variables: `UPROPERTY(BlueprintReadOnlly / EditInstanceOnly / ...)`

That being said there seems to be almost no public variable except for delegates and GamplayTags.
