I've recently been struggling with multiple file inclusion errors.
I'm working on a space arcade game and have divided my classes/objects into different .cpp
files and to make sure everything still works fine together I have build the following header file:
#ifndef SPACEGAME_H_INCLUDED
#define SPACEGAME_H_INCLUDED
//Some Main constants
#define PI 3.14159265
//Standard includes
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <vector>
using namespace std;
//SDL headers
#include "SDL.h"
#include "SDL_opengl.h"
#include "SDL_mixer.h"
#include "SDL_image.h"
//Classes and project files
#include "Player.cpp"
#include "planet.cpp"
#include "Destructable.cpp"
#include "PowerUp.cpp"
#include "PowerUp_Speed.cpp"
#endif // SPACEGAME_H_INCLUDED
And at the top of every one of my files I included (only) this header file which holds all .cpp files and the standard includes.
However, I have a Player/Ship class that has given me errors of the 'redefinition of Ship class' type. I eventually found a workaround by including preprocessor #ifndef and #define commands in the class definition file:
#ifndef PLAYER_H
#define PLAYER_H
/** Player class that controls the flying object used for the space game */
#include "SpaceGame.h"
struct Bullet
{
float x, y;
float velX, velY;
bool isAlive;
};
class Ship
{
Ship(float sX,float sY, int w, int h, float velocity, int cw, int ch)
{
up = false; down = false; left = false; right = false;
angle = 0;
....
#endif
With this workaround I lost the 'class/struct redefinition' erorrs but it gave me weird errors in my class file PowerUp_Speed that requires the Ship class:
#include "SpaceGame.h"
class PowerUp_Speed : public PowerUp
{
public:
PowerUp_Speed()
{
texture = loadTexture("sprites/Planet1.png");
}
void boostPlayer(Ship &ship)
{
ship.vel += 0.2f;
}
};
I've been getting the following errors: 'Invalid use of incomplete type 'struct Ship'' and
'Forward declaration of 'struct ship''
I believe the origin of these errors is still in my trouble with the multiple file inclusion errors.
I described every step I took in order to reduce my amount of errors but so far none of all
the posts I've found on Google helped me so that's why I'm politely asking if any of you could help me find the origin of the problems and a fix.
Usually, You do not include cpp files.
You need to only include the header files!
When you include cpp files, You end up breaking the One Definition Rule(ODR).
Usually, Your header files(.h) will define the class/structures etc and your source(.cpp) files will define the member functions etc.
As per ODR you can have only definition for each variable/function etc, including the same cpp file in multiple files creates more than one definition and hence breaks the ODR.
How should you go about this?
Note that to be able to create objects or call member functions etc, All you need to do is include the header file which defines that class in the source file which needs to create the object etc. You don't need to include source files anywhere.
What about Forward Declarations?
It is always preferred to use forward declaring classes or structures instead of including the header files, doing so has significant advantages, like:
Reduced compilation time
No Pollution of global namespace.
No Potential clash of preprocessor names.
No Increase in Binary size(in some cases though not always)
However, Once you forward declare a type you can only perform limited operations on it because the compiler sees it as an Incomplete Type. So You should try to Forward declarations always but you can't do so always.
Related
Ok so, simply said : I've included a .h into another .h and i get a compilation error telling me that the functions are already defined in main.obj
But, well i've only included Graphics.h one time so how can it be possible that main.obj also defined the Graphics.h functions ?
I got an Error LNK2005 "Already defined in main.obj".
Graphics.h contain functions that many others files will need, but for the moment we have a problem with just one file so I'd like to fix that first.
EDIT : SOLVED by spliting the header, i kept the header for the functions prototypes and I created a new Graphics.cpp for the functions definition
Here are the most concerned files, I've commented the files content so it is readable.
If I'm wrong by commenting please tell me and I'll put it on pastebin or something like that
main.cpp
#include "main.h"
using namespace std;
int main()
{
sMainData data = {};
main_Initialize(data);
while (data.config.window.isOpen())
{
main_Event(data);
main_Update(data);
main_Draw(data);
}
return 0;
}
main.h file :
#ifndef MAIN_H
#define MAIN_H
#include <SFML/Graphics.hpp>
#include "PlayerClass.h"
// Structures...
// Prototypes...
// Functions...
#endif // !MAIN_H
PlayerClass.h file :
#ifndef PLAYERCLASS_H
#define PLAYERCLASS_H
#include "AliveClass.h" // Including the mother
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
#include "Graphics.h" // <-- So here we have our man
//Class definition
#endif // !1
Graphics.h file :
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "SFML/Graphics.hpp"
// Prototypes...
// Functions...
#endif // !GRAPHICS_H
You didn't provide a minimal reproducible example, but my best guess is, you have some function implemented in the header file, while ending up including that header, either directly or indirectly, in more than one cpp file. The result is exactly the same function with exactly the same signature, being compiled in both cpp files, which causes the linker to complain.
Solutions:
Move the function out of the header and into its own cpp file (probably the best)
Find a way to only include the header in one single cpp file (probably the second best in case the header isnt yours and you don't want to touch it)
Make that function inline (probably the easiest, but technically the worst)
I have searched for a while on this, but I keep getting answers that do not answer this specific scenario.
I have a class called VisibleGameObject. I am wondering what happens if I put my normal includes in the header (so that other developers can use the same class), and put the same include in my pre compiled header stdafx.h
I don't want developers dependent on my pch.
// VisibleGameObject.h
#pragma once
#include "SFML\Graphics.hpp"
#include <string>
class VisibleGameObject
{
public:
VisibleGameObject();
virtual ~VisibleGameObject();
virtual void Load( std::string filename );
virtual void Draw( sf::RenderWindow & window );
virtual void SetPosition( float x, float y );
private:
sf::Sprite _sprite;
sf::Image _image;
std::string _filename;
bool _isLoaded;
};
Implementaion:
// VisibleGameObject.cpp
#include "stdafx.h"
#include "VisibleGameObject.h"
...
PCH:
// stdafx.h
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
When I build my project (after I have compiled once), does #include <SFML/Graphics.hpp> get recompiled every time? Because it is included in the header file of this class. I think what happens is that the pch is included first in the cpp file's translation unit and then #include <SFML/Graphics.hpp> is include guarded so the pch works normally and my include is ignored. In Visual Studio, it is an error to not include the pch first. I just want to confirm this behaviour. Does the pch get used normally and no <SFML/Graphics.hpp> code is recompiled?
If the author of the header has any salt at all, then no, it won't be recompiled.
The PCH includes the full definition, including the #ifndef, #define, #endif include guard logic. During PCH-creation the file will be pulled in, compiled, and the include guard identifier formally defined. In your source that follows any #include "stdax.h" all that precompiled content is slurped in. The source will include the suspect header for compilation. However, the preprocessor will skip all the content once the include guard's #ifndef id is found as defined. Note: It is possible it can be recompiled for a translation unit that specifically has PCH turned off, but I doubt you've done that.
In short, you're doing it correctly, and your assessment is accurate.
I've been teaching myself some OpenGL using SFML for creating windows/handling inputs, etc. My main.cpp started getting a bit unwieldy so I decided to start splitting my code up. I created a 4X_vertex.h and a 4X_vertex.cpp (4X is the name of the project) and moved the relevant functions and structs out of my main and into these files. However, when I compile, I get the error
variable or field "drawVertexArray" declared void
which from my research seems to be just an unhelpful message relating to the next error, which is
vertex was not declared in this scope
Here's my list of includes from my main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "4x_vertex.h"
#include "4x_constants.h"
My 4X_vertex.h:
#ifndef _4X_VERT_H
#define _4X_VERT_H
struct vertex{
GLfloat x,y,z;
GLfloat r,g,b;
};
void drawVertexArray(vertex v[]);
vertex* loadVertexData();
#include "4X_vertex.cpp"
#endif
The part of 4X_vertex.cpp that's giving me the trouble:
using namespace std;
void drawVertexArray(vertex v[]){
... openGL stuff...
}
All of this worked before I started moving it around so I'm assuming there's something weird going on with the includes, or something. All help is greatly appreciated!
Just some pointers. Best practice is to divide your project up into multiple source files. Typically, you would use the word "main" in the file name of the main source file (if applicable). So you might have something like...
main.cpp
feature1.cpp
feature2.cpp
tools.cpp
For your other files, you will typically name them after the class they implement. You will most often have both a .h and a .cpp. Put your declarations in the .h and your definitions in the .cpp had have the .cpp include the .h. That might give you...
main.cpp
feature1.cpp feature1.h
feature2.cpp feature2.h
tools.cpp tools.h
The modules that reference one of your classes includes it's .h as well. So, main.cpp might look like...
#include <iostream>
#include "feature1.h"
#include "feature2.h"
using namespace std;
void main(int argc, char **argv)
{ ...
cout << "Done!\n";
}
And feature1.cpp might be...
#include "feature1.h"
#include "tools.h"
feature1_class::feature1_class() { ... }
void feature1_class::AUsefulFeature(int val) { ... }
//etc.
...where feature1.h declares the class, defined constants, etc. f.g.,
#ifndef FEATURE1
#define FEATURE1
#include "tools.h"
class feature1_class
{
public:
feature1_class();
void AUsefulFeature(int val);
int APublicMember;
};
#endif
You may have noticed that tools.h is actually include twice in feature1.cpp. It is included from within the feature1.h and explicitly from the .cpp file. If you use the following pattern in your .h files ...
#ifndef TOOLS_H
#define TOOLS_H
//... do your thing
#endif
... then multiple includes shouldn't cause you any problems. And as you refactor code, it is one less thing to have to worry about cleaning up.
If you have been using a single file for all your source up till now, you may have been compiling like so...
cl main.cpp
Which gives you your .exe and .obj and maybe other files. But with multiple source files involved, it isnt much different. You can say...
cl main.cpp feature1.cpp feature2.cpp tools.cpp
There is much more to learn, but this is a start and helps you on the way to better organization of your coding thoughts.
You need to #include "4X_vertex.h" at the top of your 4X_vertex.cpp file. This will allow the .cpp file to see the declaration for the struct vertex.
In general, each file (both .h and .cpp files) needs to #include any header files which contain declarations for items used in that file. This includes the standard headers and OpenGL headers, as well as your custom ones.
I'm making an app with DragonFireSDK and I want to organize my multi thousand line app with .cpp and .h files
I get tons of errors when trying to do stuff though
So my app.cpp (main, required one) looks like this
Code:
#include "DragonFireSDK.h"
#include "SaveData.h"
#include "Structures.h"
#include "Definitions.h"
#include "Variables.h"
#include "SaveData.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Functions.cpp"
#include "AppMain.cpp"
#include "AppExit.cpp"
#include "OnTimer.cpp"
The #include "SaveData.h" through #include "Variables.h"
all have something like
Code:
#ifndef _HeaderName
#define _HeaderName
//STUFF HERE LIKE
#define player1 0
#define player2 1
//OR
typedef struct _number {
int view;
int number;
bool able;
int opacity;
};_number number[4];
//OR
int whoseturn;
int bet[5];
bool reachedmax[5];
int playerimg[5];
#endif
Now I may be doing something wrong already but here's some more...
My AppMain.cpp, OnTimer.cpp etc look like this
(AppMain(), etc are required functions too)
Code:
#include "DragonFireSDK.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Definitions.h"
#include "Structures.h"
#include "Variables.h"
#include "SaveData.h"
#include "Functions.cpp"
void AppMain() {
//STUFF HERE
};
Now this is where I think the problem is...
Functions.cpp
Code:
#include "DragonFireSDK.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "SaveData.h"
#include "Structures.h"
#include "Definitions.h"
#include "Variables.h"
//SOME FUNCTIONS
void SavePlayerMoney();
void SetInfo (int idnum, bool actuallyset = false);
void SwitchButton (int idnum, bool makeactive=true);
void DisableButton (int idnum);
double round (double number);
void SavePlayerMoney() {
//...
}
void SetInfo(int idnum, bool actuallyset) {
//...
}
void SwitchButton(int idnum, bool makeactive) {
//...
}
void DisableButton(int idnum){
//...
}
Now the errors I get after I thought if fixed all the stuff...
Code:
1>AppMain.obj : error LNK2005: "void __cdecl SwitchButton(int,bool)" (?SwitchButton##YAXH_N#Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "double __cdecl round(double)" (?round##YANN#Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "void __cdecl SetInfo(int,bool)" (?SetInfo##YAXH_N#Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "int __cdecl Digits(int)" (?Digits##YAHH#Z) already defined in App.obj
Any help is very greatly appreciated!
Don't #include the .cpp files.
The C compilation model is that each function is defined precisely once, i.e. in exactly one compilation unit (i.e. one object file). You compile each source file independently into a separate object file (#include-ing header files so that the compiler knows e.g. the prototype of functions to be used). You then link these separate object files together to form the final executable.
If you #include the .cpp files, you will end up with the same function being defined in multiple compilation units (remember that #include is basically equivalent to copy-pasting the contents into the file that's doing the including). So the linker will get confused, and give you the messages that you are seeing.
UPDATE
Oh, I see the problem is that you don't have a corresponding header file for Functions.cpp. The idea is that you also write a Functions.h, along the lines of:
#ifndef FUNCTIONS_H_
#define FUNCTIONS_H_
void SavePlayerMoney();
void SetInfo(int idnum, bool actuallyset);
void SwitchButton(int idnum, bool makeactive);
void DisableButton(int idnum);
#endif
And then you #include this header file, rather than the .cpp file.
The linker complains because functions are defined more than once. A function may only be defined in one translation unit (cpp file, after compilation it becomes an obj file) - except if it is declared inline.
You're including Functions.cpp in other units, so the function definitions from Function.cpp get duplicated into those, thus causing the linker trouble.
The solution would be to declare the functions inline - or, even better, declare them in a header (i.e. Functions.h) and define them in Functions.cpp. Any users of those functions may then #include Functions.h and have access to these functions even though they don't know their implementation.
To declare a function, do: int foo();, to actually define it, do int foo() { your code goes here}.
I think everyone answered this really well so I'm just going to give you my C++ philosophy on big projects because it seems like it is information that you may find useful.
ALWAYS separate function declarations and implementation.
It will make your life considerably easier. Declare function prototypes in a .h file, then write the implementation in a .cpp file.
For example:
// mystuff.h
#ifndef MYSTUFF_H
#define MYSTUFF_H
int myFunction(int value, char letter);
#endif
And in my .cpp file:
// mystuff.cpp
#include "mystuff.h"
int myFunction(int value, char letter) {
// insert implementation here
}
Why do this? Well one great reason is that when your code doesn't work (as it ostensibly will, an inescapable reality for any programmer), you can substitute out your .cpp file with alternate implementations without modifying the structure of your code. Not only that, there are various tricks you will discover that will rely on separating declarations and implementation that will ease your life considerably. Bottom line, do it.
Attempt encapsulation wherever possible.
If you're doing a big project (and you will notice this is true for most big projects you encounter), encapsulating similar functions, variables, and the like will save you considerable time and energy. It seems like you're making a program to play a game- have you thought about encapsulating each player into a Player or Human class, with class-specific functions for each one? If you're a C++ or Java junkie like myself, you will find that an object-oriented approach is the most effective approach 99 times out of 100 (the 1% of situations is usually where you have helper functions that don't really fit in any of the objects you've defined).
Also, encapsulation enables you to take advantage of the two other fundamental principles of object-oriented design- polymorphism and inheritance. For example, you could define a Player class, then if your game involves a computer player and a human player, you could write a separate class for each of them that inherits the basic functionality of a Player but implements each function of a Player in a different way (i.e. if there is a makeMove function, you would have a different implementation for a human than a computer. Thus, inheritance greatly simplifies your job). There are obviously many qualities of OO design that are appealing, but for what I've gleaned from your code, I'd say you would benefit the most from these ones.
Obviously, this is my own philosophy and not one that I wish to forcefully impose on you. But hopefully you will take a few helpful tips out of my terse rambling to improve the way you write code and/or avoid long lists of errors. Best of luck!
Move your function declarations to header files. For example, looks like Functions.h should contain:
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
//SOME FUNCTIONS
void SavePlayerMoney();
void SetInfo (int idnum, bool actuallyset = false);
void SwitchButton (int idnum, bool makeactive=true);
void DisableButton (int idnum);
double round (double number);
#endif
Then Functions.cpp can just include Functions.h instead of those declarations. Some header files may need to include other header files to get the appropriate types.
Finally, never #include a *.cpp file.
Its the first time I am trying to separate the class in a separate header file but I am getting an error.Please help me out.Thanks
CODE:
My main function:
#include <iostream>
#include <MyClass>
int MyClass::data;
int main()
{
cout<<"data="<<MyClass::data;
system("pause");
return 0;
}
MyClass.h
#ifndef MyClass
#define <MyClass>
class MyClass
{
static int data_;
};
#endif
Error: fatal error C1083: Cannot open include file: 'MyClass.h': No such file or directory
You should use
#include "MyClass.h"
angle brackets are for system headers.
Also it's data or data_?
Also it would be better something like
#if !defined(MYCLASS_H_INCLUDED)
#define MYCLASS_H_INCLUDED
...
#endif
#define-ing a name identical to the class name is going to be a source of problems
First good idea to separate definition and implementation in C++. Your #include directive shall use " and not < > as your header is not a system header. Or your header is not lying inside the same directory than the cpp file.
That is another topic but OO is more than just using some classes. Encapsulating static variables inside a class doesn't make them less global... At least they have another namespace...
use #include "Myclass.h" instead of #include