0

I want to create some objects that can delegate some work to its nested subobjects, but it pushes me into the circular dependency issues. Using of #ifndef directive works fine if I have only two classes (ClassA and ClassB), but this pattern doesn't work when ClassC is added. Is it possible to achieve such type of structure as shown in the code below and don't get an "undefined type" errors?

ClassA.h

    #pragma once
    #include "CoreMinimal.h"
    
    #include "ClassB.h"
    class UClassB;
    
    #include ClassA.generated.h
    
    UCLASS()
    class PROJ_API UClassA : public UObject
    {
        GENERATED_BODY()
    
        UPROPERTY()
        UClassB* ObjB;
        
    public:
        void DoDelegation()
        {
            auto* ThisInstance = this;  
            ObjB = NewObject<UClassB>();        
            ObjB->DoWorkClassB(ThisInstance);
        }
    }

ClassB.h

    
    #pragma once
    #include "CoreMinimal.h"
    
    //works nice
    #ifndef CLASSA_H
    #define CLASSA_H
    #include "ClassA.h"
    class UClassA;
    #endif
    
    //trying to use similar pattern which works with ClassA.h and ClassB.h 
    #include "ClassC.h"
    class UClassC;
    
    #include ClassB.generated.h
    
    UCLASS()
    class PROJ_API UClassB : public UObject
    {
        GENERATED_BODY()
    
        UPROPERTY()
        UClassC* ObjC;
        
    public:
        void DoDelegation()
        {
            auto* ThisInstance = this;  
            ObjC = NewObject<UClassC>();        
            ObjC->DoWorkClassC(ThisInstance);
        }
        
        void DoWorkClassB(UClassA* &ObjectClassA)
        {
            // do some stuff with ObjectClassA
        }
    }

ClassC.h

    #pragma once
    #include "CoreMinimal.h"
    
    //trying to use similar pattern which works with ClassA.h and ClassB.h
    //got "undefined type" error
    #ifndef CLASSB_H
    #define CLASSB_H
    #include "ClassB.h"
    class UClassB;
    #endif
    
    #include ClassC.generated.h
    
    UCLASS()
    class PROJ_API UClassC : public UObject
    {
        GENERATED_BODY()
        
    public:
        
        void DoWorkClassC(UClassB* &ObjectClassB)
        {
            // do some stuff with  ObjectClassB
        }
    }
Waqar
  • 8,558
  • 4
  • 35
  • 43
newMember
  • 31
  • 5
  • Code that uses the pointer must be aware of the full type so you can't have it inline inside the class. Semi-related: Use shared_ptr and weak_ptr. – Michael Chourdakis Jul 01 '20 at 11:38
  • 1
    You can also read more about "Forward declaration". – arsdever Jul 01 '20 at 11:40
  • I think you will find your answers here: https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes – Mikael H Jul 01 '20 at 11:47

2 Answers2

1

creating classes that refer to each other

Is it possible to achieve such type of structure as shown in the code below and don't get an "undefined type" errors?

Certainly. Referring to an object (with a pointer for example) of some class only requires declaration of the other class, not definition.

Simple solution is to declare both classes before defining either of them.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

It's still not fully clear for me, but at least i understood why forward declaration wasn't worked for the first time. Inline implementation of methods that do something with such referencing classes is strictly not recommended. It compiles well If function is implemented in cpp.

newMember
  • 31
  • 5