Search code examples
c++constructorcircular-dependencyforward-declaration

Will forward-declaration of two classes lead to circular dependency in the constructor?


Is this allowed? I am trying to determine if there is a risk of circular dependency in the constructor.

Header file:

class B; //forward declaration 

class A
{
public:
    std::unique_ptr<B> cObj;
    std::vector<B*> cList;
    A();
};

class B
{
public:
    B(A& aObj) : aObjLocal(aObj) {};
    void ShareData(int result);
private:
    A& aObjLocal;
};

Cpp file:

void B::ShareData(int result)
{
    for (auto& iterator : aObjLocal.cList)
    {
        (*iterator).ShareData(result);
    }
}

A::A()
{
    cObj = std::make_unique<B>(*this); // <- Will this cause circular dependecy 
}

Thanks in advance for sharing the knowledge.


Solution

  • There is no circular dependency appearing here, since B does not contain an actual object of type A but only a reference. That way, *A::cObj has a well-defined size upon construction and does not depend on the implementation details of A (if B contained an actual A instead of a reference, a circular dependency would occur, the memory required to create an A would be infinite).

    Lets have a look at a small example (I made aObjLocal public just to be able to print the address):

    int main(){                                                                                          
     A a;                                                                                               
     std::cout << "Address of a:                   " << &a << std::endl;                                                                      
     std::cout << "Address of aObjLocal of a.cObj: " << &((*(a.cObj)).aObjLocal) << std::endl;                                                
    }  
    

    The output will look something like this

    Address of a:                   0x7ffe68b95f70
    Address of aObjLocal of a.cObj: 0x7ffe68b95f70
    

    So a.cObj does contain the correct reference to a, the code works as intended (assuming this behavior is the intended one).