So I have 3 MFC dialogs:
Dialog1 - main dialog
Dialog2 - sub dialog of Dialog1
Dialog3 - sub dialog of Dialog2
XXXResourceFile.h - resource file used by Dialog2 and Dialog3; contains only resources (macro constants, typedef structs which is used only in the file, and arrays of the typedefed struct); no class
In Dialog1, I need reference of Dialog2 (for showing window/modal).
In Dialog2, I need reference of both Dialog1 ( for calling GetParent() ), and 3 (for showing window/modal)
In Dialog3, I need reference of both Dialog1 and 2 ( for calling GetParent()/ GetAncestor() )
Current design:
//Dialog1.h - by co-dev
...
#include Dialog2.h"
...
//Dialog2.cpp - by co-dev
...
#include "Dialog2.h"
#include "XXXResourceFile.h"
#include "Dialog1.h"
#include "Dialog3.h"
...
//Dialog3.cpp - my initial code/design
...
#include "Dialog3.h"
#include "Dialog2.h"
#include "Dialog1.h"
#include "XXXResourceFile.h"
My ideal design:
//Dialog1.h
#include "Dialog2.h"
...
//Dialog2.h
#include "Dialog1.h"
#include "Dialog3.h"
#include "XXXResourceFile.h"
//Dialog3.h
#include "Dialog1.h"
Now on the current design, I added #pragma once in all of these headers. I am getting error lnk 2005 (says that arrays from the XXXResourceFile is already defined in Dialog3.obj, can't double click on error since it's not on the headers nor source files but on the obj).
My questions are:
Can you comment on the current design and the ideal design of this files? What needs correction, what is missing, etc...
I don't think I've fully understood usage of #pragma once. In my knowledge (also based on what my co-devs say), it is included only in header files. What about cpp files?
Also since my problem is the inclusion of XXXResourceFile.h, is the correct usage of #pragma once supposed to be on this header? Or the files that will include this header? This bit is the part where I'm really confused.
You have header circular dependency here:
//Dialog1.h
#include "Dialog2.h"
...
//Dialog2.h
#include "Dialog1.h"
#include "Dialog3.h"
#include "XXXResourceFile.h"
//Dialog3.h
#include "Dialog1.h"
Dialog1.h includes Dialog2.h that includes Dialog1.h.
Dialog1.h includes Dialog2.h that includes Dialog3.h that includes Dialog1.h.
You can break this using forward declarations and pointer types.
// Dialog1.h
class Dialog2;
class Dialog1
{
Dialog2* ptrDialog2;
};
// Dialog1.cpp
#include "Dialog2.h"
// Dialog2.h
class Dialog1;
class Dialog2
{
Dialog1* ptrDialog1;
};
// Dialog2.cpp
#include "Dialog1.h"
Related
I have a problem with the inclusion of the vector module. It seems to there is a conflit with others modules. Here is the structure :
In the simulation.h :
#pragma once
#ifndef SIMULATION
#define SIMULATION
#include <ostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <cstdlib>
// #include <vector>
#include "File.h"
...
void afficherResultat(std::vector<Client> sortie);
...
#endif
And the File.h file :
#pragma once
#ifndef FILE
#define FILE
#include <vector>
class File {
...
std::vector<Client> l;
...
};
#endif
And I get 108 errors starting with : C4091 warning and C4430, C2065, C4229 errors...
Some people spotlight the order of the inclusions. Any Ideas ?
You are defining a macro for an identifier which is part of the standard library:
#define FILE
(see https://en.cppreference.com/w/cpp/io/c#Types for what FILE is).
Doing so is forbidden and will cause very weird errors.
Instead use names which are as unique as possible as include guards, e.g. INCLUDE_GUARD_FILE_H.
If you have an include guard there is also no need for #pragma once which is a non-standard way of solving the double inclusion problem that the include guard is also supposed to prevent.
Additionally you have not declared Client in File.h. Probably some #include for the header file defining Client is missing.
I'm trying to get my includes working, but everything I try leads to errors. Even using #pragma once doesn't work. Do you know what I made wrong?
main.cpp
#include "utility/headers/Window.h"
#include "engine/headers/Player.h"
#include "engine/headers/Chunk.h"
ChunkManager.h
#ifndef CHUNK_MANAGER_H
#define CHUNK_MANAGER_H
#include "../../utility/headers/Vector3i.h"
#include "Chunk.h"
#include <map>
class ChunkManager{...}
#endif // CHUNK_MANAGER_H
Chunk.h
#pragma once
#ifndef CHUNK_H
#define CHUNK_H
#include <glm/glm.hpp>
#include "CubeCreator.h"
#include "ChunkManager.h"
#include "../../utility/headers/Random.h"
#include "../../utility/noise/headers/Noise.h"
class Chunk{...}
#endif // CHUNK_H
Error message is 'ChunkManager' has not been declared.
Thanks in advance!
Replace #include "ChunkManager.h" with class ChunkManager;.
That's called forward declaration and solves problems like class A needs to know about class B and class B needs to know about class A.
Depending on how you use ChunkManager in class Chunk. A forward declaration might not work.
Since non of the mentioned techniques worked in my case I defined a new header file containing global variables like chunkSize. Maybe it's just impossible to do what I've tried.
However for those who might find this question here's how my imports look now:
ChunkManager.h
#include "Chunk.h"
Chunk.h
// no includes
main.cpp
#include "ChunkManager.h"
And access to chunkSize isn't done anymore by calling ChunkManager::chunkSize but instead by calling Settings::chunkSize
I'm having this issue where I cannot call the object constructor in main.cpp even after it has been included in main.h. The error message is:
C:\Users\Espresso\Projects\AZRA\Debug/../src/main.cpp:7: undefined reference to `g_editor::LevelEditor::LevelEditor()'
Where main.cpp contains
#include "main.h"
g_editor::LevelEditor g_levelEditor;
and main.h contains:
#include "g_editor/g_editor.h"
g_editor.h contains all of the header files of the objects in the library, which includes the levelEditor. g_editor.h:
#ifndef G_EDITOR_H_
#define G_EDITOR_H_
#pragma once
#include "g_editor/Objects/editor_module.h"
#include "g_editor/Objects/utility_window.h"
#include "g_editor/Objects/prompt_window.h"
#include "g_editor/LevelEditor/LevelEditor.h"
extern g_editor::LevelEditor g_levelEditor;
#endif
And finally, LevelEditor.h contains the constructor and member functions of LevelEditor:
#ifndef G_LEVEL_EDITOR_H_
#define G_LEVEL_EDITOR_H_
#pragma once
#include "../Objects/editor_module.h"
#include "Modules/collisionGrid_module.h"
#include "Modules/HUD_module.h"
#include "Modules/IO_module.h"
#include "Modules/ledge_module.h"
#include "Modules/segment_module.h"
#include "g_level/g_level.h"
using namespace g_level;
namespace g_editor
{
class LevelEditor
{
private:
std::vector<editor_module*> modules;
void loadModules();
public:
static LevelEditor& get()
{
static LevelEditor sSingleton;
return sSingleton;
}
LevelEditor();
~LevelEditor() {};
I apologize for the wall of text, I've been staring at this for a few days now and I have tried reordering the static libraries by precedence (which eliminated all issues save for this one.) Is there a design flaw in my current setup? I am using sSingletons, global externs, and static libraries.
There is no definition of LevelEditor::LevelEditor.
You are either missing a source file, or you forgot to add {}.
Edit: or, if your constructor does not do anything anyway, just remove the declaration.
Either
1) This function is missing:
LevelEditor(); // So now what does this do???? That's what is missing.
or
2) it isn't missing, but you didn't add the source module or library where this function is located to your linker settings.
I'm a little confused at why this is and i'm sure it's a basic thing I should know if i'm programming in C++ but here is the question:
I have a "Windows.cpp" and at the top it has includes of
#include <windows.h>
#include "Game.h"
#include "Mouse.h"
#include "Screen.h"
...
In my Screen.h I have the following which obviously requires information from windows.h because of the use of DWORD:
#pragma once
#include <windows.h>
class ScreenServer;
class ScreenClient
{
public:
ScreenClient( const ScreenServer &server );
DWORD GetScreenHeight();
DWORD GetScreenWidth();
...
The question is, why do I have to #include windows.h within Screen.h, when my "Windows.cpp" already has included it before "Screen.h" is included?
Short answer:
Because some other file that doesn't #include <windows.h> might include Screen.h.
A bit longer:
In general, you should always include the headers you need, where you need them, and not rely on them being included somewhere else. Use forward declarations where possible, but if you need a full type, include the header.
After fixing the previous problem (see my one other question that I have asked). I had declared more classes.
One of these is called CombatAdmin which does various things: (Header file)
#ifndef COMBATADMIN_H
#define COMBATADMIN_H
#include <string> // Need this line or it complains
#include <Player.h>
#include <Sound.h>
#include <Enemy.h>
#include <Narrator.h>
using namespace std;
class Enemy;
class Player;
class CombatAdmin // Code yet to be commented here, will come soon.
{
public:
CombatAdmin();
void healthSet(double newHealth, string playerName);
void comAdSay(string sayWhat);
void playerFindsChest(Player *player,Weapon *weapon,Armour *armour);
void youStoleOurStuffEncounter(Player *player);
void comAdWarning(string enemyName);
void comAdAtkNote(string attack, double damage,string target,string aggresor);
void entDefeated(string entName);
void comAdStateEntHp(string ent, double hp);
void comAdStateScanResults(string enemyName, double enemyHealth);
string doubleToString(double number);
string intToString(int number);
bool isRandEncounter();
void randomEncounter(Player *player,Sound *sound,Narrator *narrator);
bool combatRound(Player *player, Enemy *enemy, Sound *sound, bool ran);
void playerFindsItem(string playerName,string itemName,double itemWeight,double playerWeight);
void playerFindsGold(string playerName,double coinCnt,double playerCoinCnt);
};
#endif // COMBATADMIN_H
It is then instanced in the main.cpp file like this: (Snippet of the main.cpp file)
#include <iostream> // Required for input and output
#include <Item.h> // Item header file.
#include <Weapon.h> // Header files that I have made for my classes are needed for this program
#include <sstream> // Needed for proper type conversion functions
#include <windows.h> // for PlaySound() and other functions like sleep.
#include <time.h> // Needed to seed the rand() function.
#include <mmsystem.h> // Not sure about this one, possibly defunct in this program.
#include <stdio.h> // Needed for a similar kind of output as iostream for various functions error msgs.
#include <irrKlang.h> // The header file of the sound lib I am using in this program.
#include <Narrator.h> // The narrators's header file.
#include <Pibot.h> // Other header files of classes.
#include <Armour.h>
#include <Player.h>
#include <Weapon.h>
#include <CombatAdmin.h>
using namespace irrklang;
using namespace std;
// Forward referenced functions
void seedRandom(); // Seeds the random number so it will be random as apposed to pseudo random.
string getPlayerName(string temp); // Gets the player's new name.
int main(int argc, char* argv[])
{
// Variables and object pointers declared here.
CombatAdmin *comAd = new CombatAdmin(); // Handles combat.
Narrator *narrator = new Narrator(); // The Narrator that says stuff
Pibot *piebot = new Pibot(); // PIbot, the player's trusty companion
string temp; // Temp string for input and output
However, when I try to compile the project, I get the following error:
C:\Documents and Settings\James Moran.HOME-B288D626D8\My Documents\C++ projects\Test Project\main.cpp|59|undefined reference to `CombatAdmin::CombatAdmin()'|
I am using the Code::Blocks IDE (ver 10.05), with the GNU GCC compiler. The project is of type "Console application". I am using windows XP 32 bit SP3.
I have tried changing to search directories to include where the object files are, but no success there.
As can be seen from the code, the narrator and PIbot are instanced just fine. (then used, not shown)
My question is, therefore, what do I need to do to stop these errors occurring? As when I encountered similar "Undefined reference to x" errors before using libraries. I had just forgotten to link to them in Code::Blocks and as soon as I did, they would work.
As this class is of my own making I am not quite sure about this.
Do say if you need more information regarding the code etc.
You have declared the default constructor (CombatAdmin()) and thus prevented the compiler from automatically generating it. Thus, you either need to 1) remove declaration of the default constructor from the class, or 2) provide an implementation.
I had this kind of error and the cause was that the CombatAdmin.cpp file wasn't selected as a Build target file: Prject->Properties->Build targets
Are you sure you've to include your header as:
#include <CombatAdmin.h>
?
I think you need to include your header file as:
#include "CombatAdmin.h"
And same for other headers written by you, like these:
#include "Armour.h"
#include "Player.h"
#include "Weapon.h"
//and similarly other header files written by you!
See this topic:
What is the difference between #include <filename> and #include "filename"?
My solution was just to add a line in the header before the class defenition:
class CombatAdmin;