C++ class forward declaration

后端 未结 8 595
春和景丽
春和景丽 2020-12-03 01:52

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\         


        
相关标签:
8条回答
  • 2020-12-03 02:37

    To perform *new tile_tree_apple the constructor of tile_tree_apple should be called, but in this place compiler knows nothing about tile_tree_apple, so it can't use the constructor.

    If you put

    tile tile_tree::tick() {if (rand()%20==0) return *new tile_tree_apple;};
    

    in separate cpp file which has the definition of class tile_tree_apple or includes the header file which has the definition everything will work fine.

    0 讨论(0)
  • 2020-12-03 02:42

    The problem is that tick() needs to know the definition of tile_tree_apple, but all it has is a forward declaration of it. You should separate the declarations and definitions like so:

    tile_tree.h

    #ifndef TILE_TREE_H
    #define TILE_TREE_H
    #include "tile.h"
    
    class tile_tree : public tile
    {
    public:
        tile onDestroy();
        tile tick();
        void onCreate();
    };
    
    #endif
    

    tile_tree.cpp:

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

    Except you have a major problem: you’re allocating memory (with new), then copying the allocated object and returning the copy. This is called a memory leak, because there’s no way for your program to free the memory it uses. Not only that, but you’re copying a tile_tree into a tile, which discards the information that makes a tile_tree different from a tile; this is called slicing.

    What you want is to return a pointer to a new tile, and make sure you call delete at some point to free the memory:

    tile* tile_tree::tick() {
         if (rand() % 20 == 0)
             return new tile_tree_apple;
    }
    

    Even better would be to return a smart pointer that will handle the memory management for you:

    #include <memory>
    
    std::shared_ptr<tile> tile_tree::tick() {
         if (rand() % 20 == 0)
             return std::make_shared<tile_tree_apple>();
    }
    
    0 讨论(0)
提交回复
热议问题