0

Hi i'm trying to create a factory method, that returns a derived class of class A, I'm having trouble understanding circular declaration, I hope you can help me solve this.

Thanks.

AChildOne.cpp


#include "AChildOne.h"

AChildOne.h


#ifndef ACHILDONE_H
#define ACHILDONE_H
#include "A.h"

class A_CHILD_ONE : public A {
};

#endif

A.cpp


#include "A.h"

void A::a(){
    Factory::fact();
};

A.h


#ifndef A_H
#define A_H

#include "Factory.h"

class A {
    public:
      static void a();
};

#endif

Factory.cpp


#include "Factory.h"
A *Factory::fact(){
    return new A_CHILD_ONE;
}

Factory.h


#ifndef FACTORY_H
#define FACTORY_H

#include "A.h"
#include "AChildOne.h"

class Factory {
    public:
     static A *fact();
};

#endif

Compilation error

g++ A.cpp Factory.cpp AChildOne.cpp -o test
In file included from Factory.h:5:0,
                 from A.h:4,
                 from A.cpp:1:
AChildOne.h:5:30: error: expected class-name before ‘{’ token
 class A_CHILD_ONE : public A {
                              ^
In file included from A.h:4:0,
                 from A.cpp:1:
Factory.h:9:10: error: ‘A’ does not name a type
   static A *fact();
          ^
A.cpp: In static member function ‘static void A::a()’:
A.cpp:4:2: error: ‘fact’ is not a member of ‘Factory’
  Factory::fact();
  ^
In file included from A.h:4:0,
                 from AChildOne.h:3,
                 from AChildOne.cpp:1:
Factory.h:9:10: error: ‘A’ does not name a type
   static A *fact();
          ^
Zindan
  • 3
  • 1

1 Answers1

0

In Factory.h you try to include A.h; in A.h you try to include Factory.h.

Including Factory.h into A.cpp and removing from A.h should help.

Factory declaration depends on A interface. A declaration doesn't depend on Factory declaration but A definition does.

Also, Factory.h doesn't need to know about AChildOne.h but Factory.cpp does. So move #include AChildOne.h to Factory.cpp.

George Sovetov
  • 4,942
  • 5
  • 36
  • 57
  • `Factory.cpp: In static member function ‘static A* Factory::fact()’: Factory.cpp:3:13: error: expected type-specifier before ‘A_CHILD_ONE’ return new A_CHILD_ONE; ^ Factory.cpp:3:13: error: expected ‘;’ before ‘A_CHILD_ONE’ Factory.cpp:3:13: error: ‘A_CHILD_ONE’ was not declared in this scope` – Zindan Apr 13 '16 at 21:58
  • btw, what is the meaning when you put Factory.h in A.cpp and not in A.h? – Zindan Apr 13 '16 at 22:00
  • @Zindan As I understand, you got this error after you removed `#include AChildOne.h` from `Factory.h`. I make make answer more precise: `#include AChildOne.h` should be in `Factory.cpp`. – George Sovetov Apr 13 '16 at 22:09
  • Point is avoiding unnecessary dependencies between headers that lead to such errors. Preprocessor literally includes `.h` files, replacing `#include` statements with `.h` file content. `#ifdef` guards prevent from including each `.h` file more than once. Try to "unfold" includes manually in `Factory.cpp` and you will see that `A_CHILD_ONE` is declared before `A` and, therefore, compiler doesn't know about `A` at that moment. It's exactly what compiler tells you. – George Sovetov Apr 13 '16 at 22:20
  • Thanks, I still didn't understand why when I put it on the cpp it is working, I did understand the part that the preprocessor literally including the h files, but why it works on the cpp? Can you explain that? – Zindan Apr 14 '16 at 01:38
  • I made mistake in previous comment. This error appears when `A.cpp` is compiled. – George Sovetov Apr 14 '16 at 07:56
  • Try to include all headers manually in `.cpp` file and follow compiler using notepad. Read thoroughly what compiler tells: `A.cpp` includes `A.h`, `A.h` includes `Factory.h`, `Factory.h` includes `A.h` but because `#define A_H` (`#ifndef` guard) was "executed" when `A.h` was included first time, compiler skips `A.h` this time and `Factory.h` includes `AChildOne.h`, `AChildOne.h` include `A.h` but it's content skipped again for same reason. Compiler finally reached `A_CHILD_ONE` declaration but it doesn't know `A` at that moment because `A` declaration has not been reached yet. – George Sovetov Apr 14 '16 at 07:57