Forward Declaration

Hey, I’m afraid this is probably a bit of a noob question but I’m having trouble finding a definitive answer.

If I create a c++ class via the editor, open it and then in the construtor in the cpp add something like:
UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));

When I start typing that first UStaticMeshComponent Visual Studio recognises it enough to be able to autocomplete and I can assign it assuming I don’t need to cast. If I try and do anything with it though, I’m told it’s an incomplete type and I have to #include "Components/StaticMeshComponent.h" at the top.

My understanding of the above is that UStaticMeshComponent is forward declared and so the compiler knows what it is, but can’t do anything with it until it is defined (which happens when I include its .h file).

If I’ve understood the above correctly, then at what point is UStaticMeshComponent (and other components) forward declared? Is it when I use it as part of the line I pasted at the top of my post UStaticMeshComponent* SphereVisual = ...? Does this happen higher up in the inheritance chain? Is it something else entirely?

Thanks for your help.

Not sure of that but:

It may be linked to the fact that UE 4.15 and less used to include everything, so probably the completion tool of VS was aware of everything even tho the class is not declared.

Or it may be because the class DOES exist in your project files somewhere so VS can complete it but then tells you that it’s incomplete due to the include.

Hi Magic Kiwi (good name)
You are confusing terms, lest say you have a .h and cpp. and you want use that code inside another pair, and viceversa, this will create a circular dependency, and that means bad things for your compiler, in order to avoid this situation we use forward declaration.
Here the example to illustrate this point:

   //this is header A
#pragma once
#include "MyHeaderA.h"
#include "MyHeaderB.h"

class ClassA 
{
     Something();
};

   //this is header B
// MyHeaderB.h
#pragma once
#include "MyHeaderB.h"
#include "MyHeaderA.h"

class ClassB 
{
     Something();
};

As you can see you have been included the headers for each other, but this is wrong, the proper way is through forward declarartion:

             //this is header A
    // MyHeaderA.h
 
    class ClassB; // here this is called forward declaration, the compiler only knows the concept and is able to compile without circular dependencies
    
    class ClassA 
    {
         Something();
    };

//this is the cpp for MyHeaderA.h
#include "MyHeaderA.h"
#include "MyHeaderB.h"

ClassA::Something()
{
//using class B without problerm
}
    
       //this is header B
    #pragma once
    #include "MyHeaderB.h"
    
    class ClassB 
    {
         Something();
    };

also you can declare methods like this void SomthingElse(class ClassB* InClassB);

Now About your question, VS is very dump, the fact that is not capable to autocomplete stuff is a different history, whenever you added a module, class or something big to your project, try to regenerate your solution, this will fix the autocomplete feature 99% of cases

1 Like

Thanks for your example. I understand that VS can be a little weird which is why it surprised me that it does auto complete but won’t compile. In this case it seems that the IntelliSense error about UStaticMeshComponent being an incomplete type is correct. It knows what it is, but doesn’t have a definition which is what made me think that it must be forward declared somewhere.

Actually, even more strangely I can do:

USphereComponent* SphereComponent;
SphereComponent->InitSphereRadius(40);

and even though UsphereComponent is incomplete, IntelliSense knows what methods SphereComponent has.