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.
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…
I have three classes.
first class:
#ifndef C_LINKED_LIST_H
#define C_LINKED_LIST_H
class CLinkedList {
private:
//removed code for brevity
public:
// removed code for brevity
};
#endif
second class:
#ifndef C_SSF_FOLDER_CONTAINER_H
#define C_SSF_FOLDER_CONTAINER_H
#include "C_SSF_Folder.h"
#include "CLinkedList.h"
class C_SSF_Folder_Container {
private:
// removed code for brevity
public:
int Add_Folder(C_SSF_Folder *_pcl_SSF_Folder);
C_SSF_Folder *Get_Folder(int _i_Index);
C_SSF_Folder *Get_Folder(char *_pch_Name);
//^-----errors
};
#endif C_SSF_FOLDER_CONTAINER_H
my third class
#ifndef C_SSF_FOLDER_H
#define C_SSF_FOLDER_H
#include <windows.h>
#include <fstream>
#include "C_SSF_Folder_Container.h"
using namespace std;
class C_SSF_Folder {
public:
private:
C_SSF_Folder_Container cl_SSFFC_Folder_Container;
public:
};
#endif
my third class C_SSF_Folder.
I am including "C_SSF_Folder_Container.h"
and declaring a C_SSF_Folder_Container container.
Before declaring the variable it compiles fine. After I declare it
I get syntax errors in my C_SSF_Folder_Container
Severity Code Description Project File Line Suppression State
Error C2061 syntax error: identifier 'C_SSF_Folder' CSSFileSystem\projects\cssfilesystem\cssfilesystem\c_ssf_folder_container.h 16
Error C2061 syntax error: identifier 'C_SSF_Folder' CSSFileSystem \projects\cssfilesystem\cssfilesystem\c_ssf_folder_container.h 19
As I myself look into it I think there is a problem because my C_SSF_Folder is including C_SSF_Folder_Container.
and C_SSF_Folder_Container is including C_SSF_Folder
but the defines should take care of it? Other than that I have no clue what's the problem.
Everything is typed correctly.
You've got a circular #include -- C_SSF_Folder_Container.h #includes C_SSF_Folder.h and C_SSF_Folder.h #includes C_SSF_Folder_Container.h.
This would cause an infinite regress (and a compiler crash) except that you've got the #ifndef/#define guards at the top of your files (as you should); and because of them, instead what you get is that one of those two .h files can't see the other one, and that's why you get those errors.
The only way to fix the problem is to break the circle by deleting one of the two #includes that comprise it. I suggest deleting the #include "C_SSF_Folder.h" from C_SSF_Folder_Container.h and using a forward declaration (e.g. class C_SSF_Folder; instead.
C_SSF_Folder.h and C_SSD_Folder_Container.h are including each other(Circular Dependency).
When the compiler compiles C_SSF_Folder_Container object, it needs to create a C_SSF_Folder object as its field, however, the compiler needs to know the size of C_SSF_Folder object, so it reaches C_SSF_Folder object and tries to construct it. Here is the problem, when the compiler is constructing C_SSF_Folder object, the object has a C_SSF_Folder_Container object as its field, which is a typical chicken and egg question, both files depends on each other in order to compile.
So the correct way to do it is to use a forward declaration to break the circular dependency(including each other).
In your C_SSF_Folder.h, make a forward declaration of C_SSF_Folder_Container.
#include <windows.h>
#include <fstream>
using namespace std;
class C_SSF_Folder_Container;
class C_SSF_Folder {
public:
private:
C_SSF_Folder_Container cl_SSFFC_Folder_Container;
public:
};
#endif
Finally, include C_SSF_Folder_Container.h in your C_SSF_Folder.cpp.
You can also learn more in the following links:
Circular Dependency (Wiki):
https://en.wikipedia.org/wiki/Circular_dependency
Forward Declaration by Scott Langham
What are forward declarations in C++?
I am trying to migrate some code written in an older version of Visual Studio (VS 2006) to the 2015 version, and I stumbled upon an error in multiple files.
#ifndef C_I3E_TYPE_ARRAY_H_
#define C_I3E_TYPE_ARRAY_H_
#include "C_I3E_Type.h"
class C_I3E_Type_Array:public C_I3E_Type {
protected:
virtual void Read(FILE *p_Stream);
unsigned int m_High_Bound;}
It's about the Read method.
#include "StdAfx.h"
#include "C_I3E_Type_Array.h"
#include "C_I3E_File.h"
#include "C_I3E_Module.h"
C_I3E_Type_Array::Read(FILE *p_Stream){
unsigned int linked_type_index;
//Get the Type Index
linked_type_index = Read_Numeric_Format(p_Stream);
m_Linked_Type = m_Parent->Get_Type_ByIndex(linked_type_index);
//Get the High Bound value of the array
m_High_Bound = Read_Numeric_Format(p_Stream);}
It keeps sending me this error :
Severity Code Description Project File Line Suppression State
Error C4430 missing type specifier - int assumed. Note: C++ does not
support default-int MaskGen
d:\temp\bll\maskgen_whole_wo_dll\maskgen_all_classes_enabled\maskgen\classes\c_i3e\C_I3E_Type_Array.h 9
The error is quite descriptive, consider the line bellow:
C_I3E_Type_Array::Read(FILE *p_Stream) {
In the header file, there's a void there. So it should be:
void C_I3E_Type_Array::Read(FILE *p_Stream) {
#include "C_I3E_File.h" in the header. Add void before Read()'s definition.
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Avoiding Circular Dependencies of header files
Task.h:
#ifndef Tasks_h
#define Tasks_h
#include "Executors.h"
class Task
{
Executor *current_executor;
};
#endif Tasks_h
Executor.h:
#ifndef Executors_h
#define Executors_h
#include "Tasks.h"
class Executor
{
Task *current_task;
};
#endif Executors_h
main.cpp:
#include <conio.h>
#include <stdio.h>
#include "Tasks.h"
#include "Executors.h"
int main()
{
Executor ex;
return 0;
}
Compilation errors:
Error 1 error C2146: syntax error : missing ';' before identifier 'current_task' c:\users\rain\documents\visual studio 2010\projects\text\text\executors.h 8
Error 2 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\users\rain\documents\visual studio 2010\projects\text\text\executors.h 8
Error 3 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\users\rain\documents\visual studio 2010\projects\text\text\executors.h 8
Again... in C# i never can meet such problems, but i do my best to support C++ and use it.
Don't want to code all classes in one header file
this is just an example. there maybe be pointers instead
If you can switch to using pointers, you could replace header inclusions with forward declarations:
#ifndef Executors_h
#define Executors_h
class Task;
class Executor
{
Task *current_task_ptr;
};
#endif Executors_h
you can use forward declaration:
//#include "Executors.h"
class Executor;
class Task
{
std::shared_ptr<Executor> current_executor;
};
Another way is to use pimpl idiom:
in .h file (no executor headers/forward decl.)
class TaskImpl;
class Task
{
public:
Task();
String getExecutorName();
private:
std::unique_ptr<TaskImpl> impl;
friend TaskImpl;
};
and in .cpp
#include "Executors.h"
class TaskImpl {
public:
Executor current_executor;
String getExecutorName() { return current_executor.name; }
};
Task::Task() : impl(new TaskImpl()) {
}
String Task::getExecutorName() { return impl->getExecutorName(); }
I bet you are not aware of what you are actually doing: you are having a Task with part of it being an Executor in which part of it being a Task in which....
It is NOT a reference as in C# or Java.
To do what you actually trying to do, make use of pointer / reference in combination of forward declaration