Why declare a var as "class Type Name" and not just "Type Name"?

I’ve seen it all over the UE code, but I don’t get it.

Why declare a variable as class Type Name, like in ACharacter: class USkeletalMeshComponent* Mesh;, and not USkeletalMeshComponent* Mesh;?

Both looks to be pointers to a USkeletalMeshComponent object; is it a type of forward declaration?



It’s a kind of forward declaration called an ‘elaborated type specifier’:


It’s bad practice though, as it can go horribly wrong in the presence of namespaces and doesn’t really work for templates and enums. We try to discourage it, but some existing code (and occasionally new code) has it.

If you want a declaration, it should always be done at the correct scope (usually global scope), like this:

class USkeletalMeshComponent;

struct FThing

    USkeletalMeshComponent* Mesh;

Hope this helps,


Can you give an example where in the presence of namespaces this can go wrong? <3

For example:

namespace X
    // Will compile as taking ::Y* if a global Y has seen already, or as taking X::Y* if it hasn’t
    void Func(class Y* Param);

// Will compile only if A::B has been declared already, making it redundant as a forward declaration
void Func2(class A::B* Param);


Basically, it only really works for global stuff declaring other global stuff. And only if that global stuff isn’t an enum or template.


Thanks, that explains a lot.

…but, just a curiosity about that case in Character.h.

At the top there is a forward declaration, then variables and functions with ‘elaborated type specifier’ for the same class:

class USkeletalMeshComponent;
class ENGINE_API ACharacter : public APawn
	class USkeletalMeshComponent* Mesh;
	class USkeletalMeshComponent* GetMesh() const;
FORCEINLINE USkeletalMeshComponent* ACharacter::GetMesh() const { return Mesh; } //<- And one without elaborated type specifier

Are those just some leftover?

Yeah, it’ll be legacy stuff, or possibly copy+paste in the case of the Mesh and GetMesh() declarations. It’ll probably get tidied up at some point.