(I have read all the threads posted here and google, I was not able to fix from that)
I am having toruble with a incomplete type error when compiling. The way I am designing the project, the game pointer is unavoidable.
main.cpp
#include "game.h"
// I actually declare game as a global, and hand itself its pointer (had trouble doing it with "this")
Game game;
Game* gamePtr = &game;
game.init(gamePtr);
game.gamePtr->map->test(); // error here, I also tested the basic test in all other parts of code, always incomplete type.
game.h
#include "map.h"
class Map;
class Game {
private:
Map *map;
Game* gamePtr;
public:
void init(Game* ownPtr);
int getTestInt();
};
game.cpp
#include "game.h"
void Game::init(Game* ownPtr) {
gamePtr = ownPtr;
map = new Map(gamePtr); // acts as "parent" to refer back (is needed.)
}
int Game::getTestInt() {
return 5;
}
map.h
class Game;
class Map {
private:
Game* gamePtr;
public:
int test();
};
map.cpp
#include "map.h"
int Map::test() {
return gamePtr->getTestInt();
}
// returns that class Game is an incomplete type, and cannot figure out how to fix.
Let's go over the errors:
1) In main, this is an error:
game.gamePtr->map->test();
The gamePtr and map are a private members of Game, therefore they cannot be accessed.
2) The Map is missing a constructor that takes a Game* in Game.cpp.
map = new Map(gamePtr);
Here is a full working example that compiles. You have to provide the functions that are missing bodies, such as Map(Game*).
game.h
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
class Map;
class Game {
private:
Map *map;
public:
Game* gamePtr;
void init(Game* ownPtr);
int getTestInt();
};
#endif
game.cpp
#include "game.h"
#include "map.h"
void Game::init(Game* ownPtr) {
gamePtr = ownPtr;
map = new Map(gamePtr); // acts as "parent" to refer back (is needed.)
}
int Game::getTestInt() {
return 5;
}
map.h
#ifndef MAP_H_INCLUDED
#define MAP_H_INCLUDED
class Game;
class Map {
private:
Game* gamePtr;
public:
int test();
Map(Game*);
};
#endif
map.cpp
#include "game.h"
#include "map.h"
int Map::test() {
return gamePtr->getTestInt();
}
main.cpp
#include "game.h"
#include "map.h"
int main()
{
Game game;
Game* gamePtr = &game;
game.init(gamePtr);
game.gamePtr->map->test();
}
After doing this and creating a project in Visual Studio, I do not get any errors building the application.
Note the usage of #include guards, which your original posted code did not have. I also placed the members that were private and moved them to public in the Game class, so that main() can compile successfully.
You need to use forward declaration. Place declaration of Map class before definition of class Game:
game.h
class Map; // this is forward declaration of class Map. Now you may have pointers of that type
class Game {
private:
Map *map;
Game* gamePtr;
public:
void init(Game* ownPtr);
int getTestInt();
};
Every place where you use Map and Game class by creating instance of it or dereferencing pointer to it either through -> or * you have to make that type "complete". It means that main.cpp must include map.h and map.cpp must include game.h directly or indirectly.
Note you forward declare class Game to avoid game.h to be included by map.h, and that is fine and proper, but map.cpp must have game.h included as you dereference pointer to class Game there.
Related
Please note that I have looked at other questions on stack overflow before posting this question. I have not found any solutions that worked.
(This is simplified)
I have five files:
assets.h
#pragma once
#include "SDL2/SDL.h"
#include <map>
#include <string>
// Asset Manager class
class AssetManager {
private:
std::map<std::string, SDL_Texture*> textures;
public:
AssetManager();
~AssetManager();
void addTexture(std::string id, const char *path);
SDL_Texture *getTexture(std::string id);
};
assets.cpp
#include "assets.h"
// Constructor
AssetManager::AssetManager() {}
// Destructor
AssetManager::~AssetManager() {
// Destructor code
}
// Adds texture to "textures"
void AssetManager::addTexture(std::string id, const char *path) {
// Code for adding texture
}
// Gets texture from "textures"
SDL_Texture *AssetManager::getTexture(std::string id) {
// Code for getting texture
}
game.h
#pragma once
class AssetManager; // assets.h include in game.cpp (see below)
class Game {
private:
// Code here
public:
static AssetManager *assets;
// More code here
};
game.cpp
#include "assets.h"
#include "game.h"
AssetManager *Game::assets = new AssetManager();
// Code for game here
other_file.cpp
#include "game.h"
Game::assets->getTexture[<id>] // <-- This is where the error comes from
Even though I used a forward decleration of class "AssetsManager" in game.h, and then included assets.h in game.cpp, when included from other files it gives this error:
error: invalid use of incomplete type 'class AssetManager'
Why does it say "AssetManager" is an incomplete type?
Turns out I was missing a #include statement in other_file.cpp.
Aaand im back again with my second question and im kinda not sure about wether i should have posted all the seperate classes cuz it looks somewhat long. And im sure the solution is pretty small.
Anyways, i am at polymorphism tutorial vid that i am following and everything works fine if i follow it and put all classes in "main.cpp". But when i tried to do the same program with seperate classes (seen below) i am getting error "
E:\Codeblocks\Poly\main.cpp|11|error: cannot convert 'Ninja' to 'Enemy*' in initialization|".*
I kinda understand what the error is saying..i think.. but dont know what i did wrong since the same code was working when Enemy and Ninja class wasnt seperate but now as seperate classes its not working. I think i included those classes properly in main.cpp.
main.cpp
#include <iostream>
#include "Enemy.h"
#include "Ninja.h"
#include "Monster.h"
int main()
{
Ninja n;
Monster m;
Enemy *enemy1=&n;
Enemy *enemy2=&m;
enemy1->setAttackPower(20);
enemy2->setAttackPower(50);
n.attack();
m.attack();
return 0;
}
Enemy.h
#ifndef ENEMY_H
#define ENEMY_H
class Enemy
{
public:
Enemy();
void setAttackPower(int a);
protected:
int attackPower;
private:
};
#endif // ENEMY_H
Enemy.cpp
#include "Enemy.h"
Enemy::Enemy()
{
//ctor
}
void Enemy::setAttackPower(int a)
{
attackPower=a;
};
Ninja.h
#ifndef NINJA_H
#define NINJA_H
class Ninja
{
public:
Ninja();
void attack();
protected:
private:
};
#endif // NINJA_H
Ninja.cpp
#include "Ninja.h"
#include <iostream>
Ninja::Ninja()
{
//ctor
}
void Ninja::attack(){
std::cout<<" I am a ninja. Ninja chop! -"<<attackPower<<"\n";}
This is because your Ninja class is not inhereted from Enemy class. You must define Ninja class like this:
#include "Enemy.h"
class Ninja : public Enemy
{
public:
Ninja();
void attack();
protected:
private:
};
EDIT: I added #include directive. Without it compiler won't know, where to find Enemy class declaration.
Hello I'm pretty new to coding and have started with my first bigger project just to learn faster.
When I trying too allocate memory the error "this declaration has no storage class or type specifier" in the tool tip and then it wont compile.
#ifndef MAP_H
#define MAP_H
#include "Headers.h"
#include "Player.h"
class Player;
class Map
{
public:
Map();
Player *player;
player = new Player;
std::vector <std::string> levelData;
void Draw();
void Create();
void Open();
void Save();
};
#endif
Player *player;
player = new Player;
is not right. You cannot have a statement like the second line above in the middle of a class definition.
If you have a C++11 compliant compiler, you can use:
Player *player = new Player;
Ideally, you should initialize player in the constructor of Map. That will allow you to avoid #includeing "Player.h" in "Map.h".
Also, you should add
#include <vector>
#include <string>
since you are using
std::vector <std::string> levelData;
Player class:-
#ifndef PLAYER_H
#define PLAYER_H
class Player : public sf::Drawable, sf::Transformable
{
public:
Player(int indexWd, int indexHi);
bool load();
};
Game class :-
#ifndef GAME_H
#define GAME_H
#include "Player.h"
#include <SFML/Graphics.hpp>
class Game
{
public:
Game();
Player player(int indWd, int indHi);
void load();
};
#endif // GAME_H
Inside Game cpp file :-
#include "Game.h"
Game::Game()
{
}
void Game::load()
{
player(world.getIndexWd(), world.getIndexHi());
player.load(); //gives error
}
at player.load() in the above method, compiler is giving the following error :-
error: '((Game*)this)->Game::player' does not have class type|
Why is this error happening ?
You've declared a member function called player, and you're trying to use that as if it were a variable.
I'm guessing that it's supposed to be a data member:
Player player;
initialised in the load function:
player = Player(world.getIndexWd(), world.getIndexHi());
player.load();
Although this won't work since it doesn't have a default constructor, so must be initialised in the constructor:
Game::Game() : player(world.getIndexWd(), world.getIndexHi()) {}
which will only work if world has been initialised at this point.
Rewrite as:
void Game::load()
{
Player p = this->player(world.getIndexWd(), world.getIndexHi());
p.load();
}
player is a member function in current class and you can not apply .load on it.
You did not define your function
Player player(int indWd, int indHi);
in your .cpp file.
Also you need to either make it static in your Player class, or use an object to call it.
Player p = player(world.getIndexWd(), world.getIndexHi());
p.load();
Possible would also be
player(world.getIndexWd(), world.getIndexHi()).load();
but I would not recommend using it, as your Player object will be destroyed afterwards.
I have 3 classes namely Board, Game, and AI
i want to have the object chessBoard of Board class to be use by Game and AI, and also by the Board Class. I want them to access that single chessBoard object (sharing)
problem is, it gives me the infamous fatal error LNK1169: one or more multiply defined symbols found. Also, there are Board.h,Game.h and AI.h (only declarations in them), and i also have their corresponding .cpp files. Each .h files have guards included (#ifndef _XXXXXX_H_)
I tried to include Board chessBoard inside Board.h file (just below the class), and it seems guards are not working.
Error 7 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\Board.obj CHESSv3
Error 8 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\Game.obj CHESSv3
Error 9 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\ProgramEntryPoint.obj CHESSv3
AI.h
#ifndef _AI_H_
#define _AI_H_
#include <iostream>
#include <string>
using namespace std;
struct node {
string position;
string nextPosition;
float score;
int level;
float totalscore;
node* up;
node* right;
node* left;
bool approved;
string move;
};
class AI {
private:
//string board;
//string board[8][8];
int score1;
int maxscore;
int totalscore;
public:
void GetBoard(string[][8]);
void AnalyzeMyPositions();
void ExecuteAdvanceHeuristicMove();
};
#endif
Game.h
#ifndef _GAME_H_
#define _GAME_H_
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
class Game {
public:
char WhosTurn();
bool Playable();
bool GetMoveFromPlayer();
void TurnOver();
Game();
private:
char turn;
};
#endif
Board.h
#ifndef _BOARD_H_
#define _BOARD_H_
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
class Board {
public:
bool SquareChecker(string);
bool MoveChecker(string);
Board();
void PrintBoard();
int Execute(string);
void UnExecute();
string CB[8][8];
private:
char turn;
vector<string> BoardRecord;
stack<string> CBR;
//string CB[8][8];
};
Board chessBoard;
#endif
If you really want to do this, you need to make the declaration of the object extern in the header Board.h:
extern Board chessBoard;
You then provide a declaration in Board.cpp:
Board chessBoard;
Much better, though would be to create it in enclosing code and pass it (by reference) to the constructors of the other classes.
What you are looking for is the Singleton design pattern which can achieved in the following way:
// Board.h
class Board {
private:
static instance_;
public:
static Board *instance();
}
// Board.cpp
Board *Board::instance_ = NULL;
Board *Board::instance() {
if (!instance_)
instance_ = new Board();
return instance_;
}
Mind that this pattern can either be seen as good or bad, if you don't like using it you should consider passing the reference of an instantiated Board class to all the requiring ones and keep it stored in each object as an instance variable. Something like:
Game::Game() {
this->board = new Board();
this->ai = new AI(board);
// or better this->ai = new AI(this) so AI can access all game methods
}
Your problem could be that there could be 3 different chessBoard definitions because you might be adding 3 different #include "Board.h". Please make only a single object at a place where you have more control rather than creating it globally inside Board.h
Did you try it like this? Include the necessary include declarations only in the .cpp files.
//Board.h
class Board {};
//Game.h
class Board;
class Game {
Board* myBoard;
public:
void setBoard(Board*);
};
//AI.h
class Board;
class AI {
Board* myBoard;
public:
void setBoard(Board*);
};
void main() {
Board chessBoard;
Game g;
g.setBoard(&chessBoard);
AI ai;
ai.setBoard(&chessBoard);
}