0

i have a problem to compile the classes with cyclic dependency, and i can not find the way to compile my code

the main problem is appeared in chain of classes that has dependency to each others

for example i have 6 header files(Classes) (A, B, C, D, E, F)

A included in E

F, D included in A

E included in F, D

now i have a loop and cant fix it

i simplify the problem then create the simple example to show what is my exact problem

A.h

#ifndef A_H
#define A_H
#include "B.h"

class A
{
public:
    static A& getInstance()
    {
        static A  instance; 
        return instance;
    }
    int i;
    int sum()
    {
        return i+B::getInstance().j;
    }
private:
    A() {}
};
#endif

B.h
#ifndef B_H
#define B_H
#include "A.h"

class B
{
public:
    static B& getInstance()
    {
        static B  instance; 
        return instance;
    }
    int j;
    int sum()
    {
        return j+A::getInstance().j;
    }
private:
    B() {}
};
#endif
main.cpp

#include "A.h"
#include "B.h"
#include <iostream>
int  main()
{

    A::getInstance().i=1;
    B::getInstance().j=2;
    int t1=A::getInstance().sum();
    int t2=B::getInstance().sum();
    std::cout<<t1<<std::endl;
    std::cout<<t2<<std::endl;
    return 0;
}


g++ main.cpp
In file included from A.h:3:0,
                 from main.cpp:1:
B.h: In member function ‘int B::sum()’:
B.h:17:12: error: ‘A’ has not been declared
   return j+A::getInstance().j;

is there any way or solutions to resolve this?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Mohsen
  • 59
  • 1
  • 8
  • 1
    Use forward declarations and move implementations into `.cpp` files. – Evg Nov 24 '19 at 08:49
  • 1
    Possible duplicate of [How to forward declare a member function of a class to use in another class?](https://stackoverflow.com/questions/11344195/how-to-forward-declare-a-member-function-of-a-class-to-use-in-another-class) – nivpeled Nov 24 '19 at 08:50
  • forward declarations dose not allow to use the class member. also i can not put the implementation to cpp file, this is just sample, i have headers with about 1000 line of code and it is not just two file, about 10 header. i want to find solution to resolve this concept not only this simple example – Mohsen Nov 24 '19 at 08:52
  • Not related to forward declarations, in forward declarations you just define the class and can not use the member of the class, it mean the members does not available, this is the usage of member of one class in to another one not only getting the object of class. – Mohsen Nov 24 '19 at 08:54
  • @Mohsen, you should point the implementation constraints in the question. – Erdem Tuna Nov 24 '19 at 09:29

1 Answers1

2

If you can't use .cpp files for some reason, you can do this:

a.h:

#pragma once

class A {
public:
    static A& getInstance();
    int i;
    int sum();

private:
    A();
};

a_impl.h:

#pragma once
#include "a.h"
#include "b.h"

inline A& A::getInstance() {
    static A instance;
    return instance;
}

inline int A::sum() {
    return i + B::getInstance().j;
}

inline A::A() {
}

b.h:

#pragma once

class B {
public:
    static B& getInstance();
    int j;
    int sum();

private:
    B();
};

b_impl.h:

#pragma once
#include "a.h"
#include "b.h"

inline B& B::getInstance() {
    static B instance;
    return instance;
}

inline int B::sum() {
    return j + A::getInstance().i;
}

inline B::B() {
}

And then first include declarations a.h and b.h, and then implementations a_impl.h and b_impl.h:

#include "a.h"
#include "b.h"
#include "a_impl.h"
#include "b_impl.h"
#include <iostream>

int main() {
    A::getInstance().i = 1;
    B::getInstance().j = 2;
    int t1 = A::getInstance().sum();
    int t2 = B::getInstance().sum();
    std::cout << t1 << std::endl;
    std::cout << t2 << std::endl;
}

Now it will compile. In this particular example, B (or A) could've been implemented inside class definition (so, no b_impl.h). I separated declarations and definitions for both classes for the sake of symmetry.

Evg
  • 25,259
  • 5
  • 41
  • 83