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\
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.
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>();
}