I wanted to run the game by testing the spawner. I thought that I had properly declared the Spawner class by calling its header file in SceneGame.hpp
When I wanted to use the Spawner* as a vector variable, I thought there would be no compiler errors, but I was wrong.
The source of the error comes from declaring the variable vector spawner_list
Relevant files:
Spawner.hpp
#pragma once
#include <SFML\Graphics.hpp>
#include "weapon.hpp"
#include "movement.hpp"
// forward declare
class EnemyTemplate;
/*
Spawner will create enemies and/or power ups
For spawning enemies, they will recieve one weapon and one movement type
for powerups, only one will spawn and the spawner would disappear afterwards
The spawner will create entities through the following:
Spawn gap: the amount of time to wait between making enemies, in frame ticks
Spawn limit: the amount of enemies to make before being removed
*/
class Spawner{
private:
int spawnGapTime;
int spawnGapSet;
// If you plan to spawn finite enemies, then use constructor
int spawnLimit = -1;
EnemyTemplate* enemyData;
Weapon* givenWeapon;
Movement* givenMovement;
int ticks;
public:
Spawner(Weapon*, Movement*, EnemyTemplate*, std::vector <int>);
void update();
void spawn_enemy();
void spawn_count();
~Spawner(){
delete givenWeapon;
delete givenMovement;
delete enemyData;
};
};
SceneGame.hpp
#pragma once
#include <SFML\Graphics.hpp>
#include "scene.hpp"
#include "game.hpp"
#include "entity.hpp"
#include "movement.hpp"
#include "weapon.hpp"
#include "player.hpp"
#include "collisionGrid.hpp"
#include "spawner.hpp"
// forward declare
class BulletTemplate;
class SceneGame : public Scene{
private:
// skipping some code
std::vector <Spawner*> spawner_list; // The source of the error
public:
SceneGame(Game* game);
// skipping some code
};
Is there any way I can fix this undeclared identifier problem without having to forward declare Spawner?
C2065: 'class' undeclared identifier
If that is the literal text of the error message, you're compiling as C, not as C++.
If it isn't the literal text of the error message, you should have posted the literal text of the error message.
Related
I've been trying to pass my Graphics Manager class to both my Robot and Room class.
But when attempting to pass the class by reference I get 3 errors regarding the pass by reference.
These are the errors I'm referring to:
C2143 syntax error: missing ';' before '*'
C4430 missing type specifier - int assumed. Note: C++ does not support default-int
C2238 unexpected token(s) preceding ';'
I have attempted to change the way I've been passing the classes but with no luck, I have highlighted the areas in which is causing the error as well as the code that i have tried to use to fix the problem.
Any advice in how i could go about fixing these errors is highly appreciated.
I have not included the full .cpp files as they are quite large but I will include a link to a pasteBin with the full script.
GrapicsManager.h
#pragma once
#include <iostream>
#include <SFML/Graphics.hpp>
#include "Room.h"
#include "Robot.h"
class GraphicsManager
{
public:
Room* room; //This does not Flag Up Errors
Robot* robot; //This does not Flag Up Errors
Robot.h
#pragma once
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/System/String.hpp>
#include "GraphicsManager.h"
//#include "Room.h" //This what i had
class Room; //This is what i changed
//class GraphicsManager; //Wasnt sure if i should use it this
//way
class Robot
{
public:
//Graphics Variables
Room* room; //This works after the change
Robot* robot; //This works after the change
GraphicsManager *gm; //This throughs up the error
//This Is what i attemped to use with no effect
//GraphicsManager* gm = new GraphicsManager(room, robot);
Robot.cpp https://pastebin.com/Xd1A3Vii
#include "Robot.h"
Robot::Robot()
{
gm = new GraphicsManager(room, robot); //This tells me gm is
//not declared
this->room = room; //This does not flag up errors
this->robot = robot; //This does not flag up errors
//Room &room = *rm; // attempted to use this but decided not
//to
}
Room.h
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/System/String.hpp>
#include "GraphicsManager.h" //
//#include "Robot.h" //what i orginally had
//class GraphicsManager; //i decided not to do it this way
class Robot; //What i changed it to
class Room
{
public:
//Reference to other classes
Room* room; //This doesnt throw errors
Robot* robot; //This doesnt throw errors
//Refference to graphics manager
GraphicsManager *gm; //This throws the three errors mentioned
};
Room.cpp https://pastebin.com/6R6vnVfy
#include "Room.h"
Room::Room()
{
gm = new GraphicsManager(room, robot);
this->room = room;
this->robot = robot;
It's the classic cicular include issue. GrapicsManager.h includes Room.h and Robot.h which each include GrapicsManager.h again. Now, for example, when compiling GraphicsManager.cpp you include GrapicsManager.h. But before you ever get to the GraphicsManager class definition, you first include Room.h. From there you go straight to include GrapicsManager.h again, but since you have a #pragma once in there, the compiler will simply skip that include. By the time the compiler then gets to the GraphicsManager *gm; member declaration in Room.h, is has never seen a declaration of a type named GraphicsManager. The error message that Visual C++ gives you then
C4430 missing type specifier - int assumed. Note: C++ does not support default-int
is arguably a bit unintuitive. At the point where it encounters the identifier GraphicsManager, an identifier can only mean the start of a declaration. Since GraphicsManager is not a known type, the compiler assumes that identifier must be the name of the entity that is supposed to be declared and you just forgot to specify the type. That's why you get the error message you see. C in the olden days used to allow you to omit the type specifier in a declaration which would just mean to use int as a default. So you would see this error as a result of trying to compile ancient, non-standard C code. That's why the error message contains the explicit note that that's not allowed…
You already added forward declarations for Room in Robot.h and for Robot in Room.h. You'll have to do the same for GraphicsManager…
Im a fairly new programmer so I may not be understanding typedef correctly.
I have 2 classes Enemy.cpp and AI.cpp.
My AI.cpp needs values from Enemy.cpp to be able to process its movements etc. In AI.cpp I hold pointers to values such as position, speed and an enum for the direction the enemy is facing.
The Errors I get are listed below. If there is a more simple way to link an enum variable between classes, im all ears.
below is a working example of the error.
///////MAIN.H/////////////
#ifndef _MAIN_H_
#define _MAIN_H_
#endif // ! _MAIN_H_
///////////////////////////
////////MAIN.CPP///////////
#include "AI.h"
#include "Enemy.h"
int main(int argc, char* args[])
{
Enemy enemy;
}
//////////////////////////////
//////////ENEMY.H///////////////
#ifndef _ENEMY_H_
#define _ENEMY_H_
#include "AI.h"
class Enemy
{
public:
Enemy();
enum Facing
{
LEFT = 0,
RIGHT
};
protected:
AI* EnemiesAI;
//try this as a pointer
Facing EnemyDirection;
};
#endif
//////////////////////////////////
///////////ENEMY.CPP////////////////
#include "Enemy.h"
Enemy::Enemy()
{
EnemiesAI = new AI;
EnemiesAI->LinkEnemyToAI(&EnemyDirection);
}
////////////////////////////////////
/////////////////AI.H//////////////
#ifndef _AI_H_
#define _AI_H_
#include "Enemy.h"
class AI
{
public:
/*this needs to be a pointer, otherwise I have to pass the
value into AI on every update*/
typedef Enemy::Facing *ThisFacing; //Error 3
void LinkEnemyToAI(ThisFacing facing);
private:
//This is a pointer to a Enemy::Facing object
ThisFacing mFacing;
};
#endif
///////////////////////////////////////
////////////////AI.CPP/////////////////
#include "AI.h"
void AI::LinkEnemyToAI(ThisFacing facing)
{
mFacing = facing;
}
////////////////////////////////////////
Error C2653 'Enemy': is not a class or namespace name ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 11
Severity Code Description Project File Line
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 11
Severity Code Description Project File Line
Error C3646 'mFacing': unknown override specifier ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 17
Severity Code Description Project File Line
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 17
Severity Code Description Project File Line
Error C2660 'AI::LinkEnemyToAI': function does not take 1 arguments ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\enemy.cpp 7
Severity Code Description Project File Line
Error C2061 syntax error: identifier 'ThisFacing' ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 13
Severity Code Description Project File Line
Error C2238 unexpected token(s) preceding ';' ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\enemy.h 23
Using include-guards here doesn't help really, because Enemy.h depends on AI.h which depends on Enemy.h and so on forever.
You have to break that chain, and the easiest way to break it is through something called forward declarations.
If you look closer in the Enemy.h header file, all it uses of the AI class is to declare a member variable which is a pointer to AI. That means you don't need the full definition of AI, you only need to tell the compiler that the class AI exists. Something like
#ifndef ENEMY_H
#define ENEMY_H
class AI; // Forward declaration of the AI class
class Enemy
{
public:
Enemy();
enum Facing
{
LEFT = 0,
RIGHT
};
protected:
AI* EnemiesAI;
//try this as a pointer
Facing EnemyDirection;
};
#endif // ENEMY_H
Now in the Enemy.cpp file you still need to #include "AI.h" since the full definition of the class is needed there.
This forward declaration isn't really possible in the AI.h header file, since in it you use the enumeration Enemy::Facing. However, since Enemy.h no longer includes AI.h there's no longer the circular dependency.
Also note that I changed the header guard macro to not have leading underscores, since all symbols with a leading underscore follower by an upper-case letter is reserved in all scopes. See e.g. this question and its answers for more details.
This is my first question, so I apologize in advance for any things about stack overflow that I may not be aware of!
The issue I am having is that I am making a simple SDL program, currently it is just supposed to draw a PNG image (Assets/Board.png) to the screen, but I am being faced with many errors to do with the two classes communicating with each other, I think that I have circular inclusion errors. But I have been trying to fix the problem for days and I haven't been able to solve it.
Here are the errors that I am getting:
http://imgur.com/gallery/vq3XLwU/new
(Here is a text version of it, but the formatting is bad sorry)
1>d:\code\c++\games\chess\chess\manager.h(41): error C2079: 'Manager::Tex' uses undefined class 'Render'
1>d:\code\c++\games\chess\chess\render.h(32): error C2146: syntax error : missing ';' before identifier 'manager'
1>d:\code\c++\games\chess\chess\render.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\code\c++\games\chess\chess\render.h(32): error C2146: syntax error : missing ';' before identifier 'manager'
1>d:\code\c++\games\chess\chess\render.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
(I have used an image because the formatting of the image is easier to read.)
(Also click on the image in imgur to see the zoomed in version)
You can download the entire code project here (ZIP FILE):
https://www.mediafire.com/?og21315fc1d58sk
But here is the code that I think is causing the issues:
(Manager.h file)
//Include guards.
#pragma once
//Headers.
#include "Render.h"
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
//Namespaces.
using namespace std;
//Enumerator.
enum State { Play, Exit };
class Manager
{
public:
Manager(); //Constructor.
~Manager(); //Destructor.
//Rendering.
SDL_Window* Window;
SDL_Surface* Screen;
SDL_Renderer* Renderer;
//Functions.
void Run();
void Init();
void Close();
void Input();
void Update();
void Error(string);
//Game variables.
State state;
Render Tex;
private:
//Constant values.
const int WINDOW_POS_X = SDL_WINDOWPOS_CENTERED;
const int WINDOW_POS_Y = SDL_WINDOWPOS_CENTERED;
const int INIT_FLAGS = SDL_INIT_VIDEO;
const int SCREEN_HEIGHT = 600;
const int SCREEN_WIDTH = 600;
};
(And here is the Render.h file)
//Include guards.
#pragma once
//Headers.
#include "Manager.h"
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
//Namespaces.
using namespace std;
class Render
{
public:
Render(); //Constructor.
~Render(); //Destructor.
//Functions.
void Draw(int, int); //Draws texture at position.
void Load(string); //Loads texture from path.
void Deallocate(); //Destroy texture.
//Getter functions.
int GetHeight() { return Height; };
int GetWidth() { return Width; };
private:
SDL_Texture* Texture; //Actual image.
Manager manager; //Manager class.
int Height; //Height of image.
int Width; //Wdith of image.
};
So in conclusion, I am having errors related to the class objects, which I believe are being caused by circular inclusion, despite my research I have not been able to fix these issues. I would greatly appreciate any help with this issue.
P.S I know I am not supposed to use the std namespace, instead I must write std::foo, I am aware, so please don't comment about it!
In C++ "ownership" is a very important concept. A class "owns" its members. The problem is you have two objects and you've told the compiler that both "own" the other, which won't do. You have to decide which of them owns the other, and has it as a member (or maybe neither owns the other). At least one class must refer to the other, rather than listing it as a child/member. And the best sort of reference is a pointer.
class Manager;
// this forward declaration tell the compiler the class exists, but
// we don't care about the details yet, so we won't include the header.
// if we try to include it, that header refers to Render, which the compiler
// hasn't seen yet, so the compiler will fail.
class Render
{
public:
Render(Manager* parent_); //Constructor.
...stuff...
Manager* parent;
};
Cpp file:
#include "manager.h"
#include "render.h"
Render::Render(Manager* parent_)
: parent(parent_)
{}
SUGGESTIONS:
1. Eliminate the "Render.h" include:
There doesn't seem to be anything in "Manager.h" that needs anything in "Render.h" - so why include it?
Similarly, 2. Eliminate the "Manager.h" include.
You can simply use a "forward declaration", instead of including the whole class interface (.h file).
These links might help:
C++ circular include
Headers and Includes: Why and How
Okay, I think that I have solved the problem, thanks to a variety of comments. The solution may not be ellegant but it works. Instead of defining the Render Tex variabel inside the Manager header, I declared it inside the Manager.cpp class. Once I had done that I can #include "Render.h" inside the Manager .cpp file. I dont know if that explanation is clear but here is the top of the manager.h file:
//Include guards.
#pragma once
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
And here is the top of the Manager.cpp file:
//Header.
#include "Manager.h"
#include "Render.h"
//Librarys.
#include <iostream>
//Objects.
Render Tex;
I'm having trouble understanding the implementation of an image manager. I built one based off of this tutorial and it works great in itself, but I have no idea how to use it. In my tic tac toe game, I have an engine class which is self explanatory, a Board class which holds the game board (which has only one image) and a Box class, which has two possible images (X or an O), and then the ImageManager class from the tutorial (code to follow). I want to have just one instance of my ImageManager in my Game Engine, then instances of other classes such as my board and boxes can efficiently pull their images from the ImageManager. However, I have had no luck with making an ImageManager instance inside my Engine class. Here's how I have gone about this:
Engine.h:
#pragma once
#include "stdafx.h"
#include "SFML/Graphics.hpp"
#include "ImageManager.h"
#include "Board.h"
class Engine{
public:
Engine();
~Engine();
void Go();
ImageManager &GetManager();
private:
void ProcessInput();
void Update();
void Render();
void FillVector();
ImageManager imgr;
Board board;
sf::Sprite gameBoard;
sf::RenderWindow window;
sf::Event event;
};
So now I have my instance of ImageManager, and an accessor method so that any other class can retrieve it, like so:
Board.h
#include "Box.h"
#include "SFML/Graphics.hpp"
#include "ImageManager.h"
#include "Engine.h"
class Board{
public:
Board();
~Board();
std::vector<Box> &GetBoxes();
sf::Sprite GetGameBoard();
private:
sf::Sprite gameBoard;
Engine e;
std::vector<Box> boxes;
};
Board.cpp
#include "stdafx.h"
#include "Board.h"
Board::Board(){
e.GetManager().AddResourceDirectory("images/");
//error checking, images/ is indeed in the vector
//std::cout << imgr.GetResourceDirectory()[0];
gameBoard.setTexture(e.GetManager().GetImage("t3board.png"));
}
So, in theory, my instance of my Engine gets my instance of my ImageManager, which I can use just like if I declared it itself in my board class. But then I get the errors:
error C2146: syntax error : missing ';' before identifier 'e'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2146: syntax error : missing ';' before identifier 'board'
I know this is a lot, but this is my first game and I'm just really lost and tired of never knowing where to put things. Can somebody please tell me how to get this ImageManager working correctly?
so this obviously isn't the real error, but i have no idea what the actual error is because the symptom is so vague. I'll just include the files here and you guys tell me where and what you think it might be causing the undeclared identifier error.
system.h(66): error C2065: 'EntityManager' : undeclared identifier
system.h
/*******************************************************************************
filename: System.h
Author:
Date: November 13, 2010
********************************************************************************/
#ifndef SYSTEM_H
#define SYSTEM_H
#include <string>
#include <memory>
//The interfaces for the framework elements.
#include "I_OS.h"
#include "I_Graphics.h"
//The derived interface elements tailored to the platform.
#include "Windows_module.h"
#include "D3D11_module.h"
#include "EntityManager.h"
// ** AUTHOR NOTE ** temporary until ini file reading is implemented
#define FULL_SCREEN false
/*******************************************************************************
Purpose:
This will be the central object that is responsible for containing and
systematically initializing, updating per frame, and shutting down ALL the objects
responsible for the various internal workings of the framework. This will also
serve as the nexus for all external entities to retrieve data, interface with engine
elements, as well as interfacing between eachother.
********************************************************************************/
class System
{
public:
/* All framework elements and interfaces contain an Initialization context to be
created outside, filled out, and passed into the Initalize function. This is to
maintain polymorphic similar function declarations, while still having variable
parameters */
class InitializeContext
{
public:
HINSTANCE hinstance;
};
System();
~System();
bool Initialize(InitializeContext &);
void Run();
void Shutdown();
public:
//pointer declarations of interface types for each framework element
std::shared_ptr<I_OS> m_os;
std::shared_ptr<I_Graphics> m_graphics;
std::shared_ptr<EntityManager> m_EntityManager;
};
/* This will be the global pointer that all entities will use to access the
public interface pointers to the entire framework.
** AUTHOR NOTE ** : all entities should refer to the interfaces, and non platform
specific elements to maintain crossplatform compatibility, (if it can be avoided)*/
extern std::shared_ptr<System> g_System;
#endif
EntityManager.h
/*******************************************************************************
filename: EntityManager.h
Author:
Date: October 27, 2011
********************************************************************************/
#ifndef ENTITY_MANAGER_H
#define ENTITY_MANAGER_H
#include <vector>
#include <map>
#include <fstream>
#include <memory>
#include "EntityBase.h"
#include "EntityList.h"
/*******************************************************************************
Purpose:
This wil be the object responsible for managing and updating all the various Entities
currently rendered in a scene. It reads from a scene file and dynamically creates instances
of the objects listed to be stored in a vector. these objects can be accessed individually
by either index or unique string identifier, or you can obtain a vector that contains
objects of the same class type.
********************************************************************************/
class EntityManager
{
public:
bool Initialize();
bool Frame();
void Shutdown();
private:
BaseFactory m_factory;
std::vector <std::shared_ptr<BaseEntity> > m_EntityList;
std::map<std::string, std::shared_ptr<BaseEntity> > m_EntityByNameList;
std::map<std::string, std::vector<std::shared_ptr<BaseEntity> > > m_EntityByClassList;
};
#endif
So is there anything wrong with these to be causing EntityManager to be undeclared? It's the only error in the output. Think you need anymore files and i'll include them.
This is normally caused by the circular inclusion of header files. In your case, it looks like either EntityBase.h or EntityList.h includes System.h. The simplest way to solve this is to remove #include "EntityManager.h" from System.h and forward declaring class EntityManager; in system.h. Note that you need to do #include "EntityManager.h" in system.cpp.