Search code examples
c++classforward-declaration

C++ class forward declaration


When I try to compile this code, I get:

52 C:\Dev-Cpp\Projektyyy\strategy\Tiles.h invalid use of undefined type `struct tile_tree_apple' 
46 C:\Dev-Cpp\Projektyyy\strategy\Tiles.h forward declaration of `struct tile_tree_apple' 

some part of my code:

class tile_tree_apple;

class tile_tree : public tile
{
      public:
          tile onDestroy() {return *new tile_grass;};
          tile tick() {if (rand()%20==0) return *new tile_tree_apple;};
          void onCreate() {health=rand()%5+4; type=TILET_TREE;};        
};

class tile_tree_apple : public tile
{
      public:
          tile onDestroy() {return *new tile_grass;};
          tile tick() {if (rand()%20==0) return *new tile_tree;};
          void onCreate() {health=rand()%5+4; type=TILET_TREE_APPLE;}; 
          tile onUse() {return *new tile_tree;};       
};

I dont really know what to do, I searched for the solution but I couldn't find anything simmilar to my problem... Actually, I have more classes with parent "tile" and It was ok before...

EDIT:

I decided to change all returned types to pointers to avoid memory leaks, but now I got:

27 C:\Dev-Cpp\Projektyyy\strategy\Tiles.h ISO C++ forbids declaration of `tile' with no type 
27 C:\Dev-Cpp\Projektyyy\strategy\Tiles.h expected `;' before "tick"

Its only in base class, everything else is ok... Every function in tile class which return *tile has this error...

Some code:

class tile
{
      public:
          double health;
          tile_type type;
          *tile takeDamage(int ammount) {return this;};
          *tile onDestroy() {return this;};
          *tile onUse() {return this;};
          *tile tick() {return this};
          virtual void onCreate() {};
};

Solution

  • In order for new T to compile, T must be a complete type. In your case, when you say new tile_tree_apple inside the definition of tile_tree::tick, tile_tree_apple is incomplete (it has been forward declared, but its definition is later in your file). Try moving the inline definitions of your functions to a separate source file, or at least move them after the class definitions.

    Something like:

    class A
    {
        void f1();
        void f2();
    };
    class B
    {
       void f3();
       void f4();
    };
    
    inline void A::f1() {...}
    inline void A::f2() {...}
    inline void B::f3() {...}
    inline void B::f4() {...}
    

    When you write your code this way, all references to A and B in these methods are guaranteed to refer to complete types, since there are no more forward references!