I have header that contains class declaration.
DialogExInput.h
#include "Stdafx.h"
#pragma once
#include "utils.h"
// CDialogExInput dialog
class CDialogExInput : public CDialogEx
{
DECLARE_DYNAMIC(CDialogExInput)
public:
CString timeRemainedSecStr;
CString Caption;
int TimeoutSec;
int MinDataSize;
int MaxDataSize;
CString text;
int timeRemainedSec;
void AssignParams (DialogOptions* dOp);
CDialogExInput(UINT nIDTemplate, CWnd *pParent = NULL);
afx_msg void OnTimer(UINT uTime);
virtual ~CDialogExInput();
void SetOnTop();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
};
Compiler can't find DialogOptions, which is declared in utils.h. And DialogExInput.h includes utils.h.
Error 1 error C2061: syntax error : identifier 'DialogOptions'
utils.h
#ifndef UTILS_H
#define UTILS_H
#include "InputDialog.h"
#include <string>
using namespace std;
#define CURRENCY_EUR 978
extern HWND AuthMsgHWND;
struct DialogOptions {
CString Caption ;
CString DefaultText;
int MaxTimeoutExpected;
int MaxChars;
int MinChars;
int ModalResult;
int inputTimeRemained;
} ;
void ErrorExit();
const wchar_t *GetWC(const char *c);
bool GetProductAndVersion(CStringA & strProductName, CStringA & strProductVersion);
void doInputDialog(DialogOptions *pDo, string & answer);
void doYesNoDialog(DialogOptions *pDo, string & answer );
wstring termToWchar (const char* value);
string getTime(string format = "%d-%m-%Y %I:%M:%S" );
#endif UTILS_H
So where is problem? Why DialogExInput.h don't see DialogOptions
A circular include exists
DialogExInput.h
#pragma once
#include "utils.h"
InputDialog.h
#include "DialogExInput.h"
utils.h
#include "InputDialog.h"
So if you include InputDialog.h before any of the others (where it goes wrong) then the files will be read in the following order
Inputdialog.h
DialogExInput.h
utils.h
and DialogExInput can therefore not see the content of utils.h.
If you add the forward declaration of struct DialogOptions at the the start of DialogExInput .h
#include "Stdafx.h"
#pragma once
#include "utils.h"
struct DialogOptions; // forward declare as you only use a pointer/reference to it.
// CDialogExInput dialog
class CDialogExInput : public CDialogEx
Making a separate include file is also an option.
Also you should break the circular include, checking if you really need those includes. If you don't you it will get back and bite you later.
Related
Error C2079 'Message::simbolo' uses undefined class 'Symbol'
is generated on this line when compiling
Symbol simbolo;
This is my C++ code:
class Message
#pragma once
#include <string>
#include "Symbol.h"
#include "SharedEditor.h"
class SharedEditor;
class Symbol;
class Message
{
private:
SharedEditor* sender;
int action; //1 inserted 2 deleted
Symbol simbolo;
public:
Message();
Message(SharedEditor* sender, Symbol nuovosimbolo, int action);
~Message();
};
class Symbol
#pragma once
#include "SharedEditor.h"
#include <vector>
class SharedEditor;
class Message;
class Symbol
{
char character;
int siteID;
SharedEditor* generator;
std::vector<int> position;
public:
Symbol();
Symbol(char ch, SharedEditor* source, int ID, std::vector<int> pos);
~Symbol();
};
class SharedEditor:
#pragma once
#include "NetworkServer.h"
#include "Message.h"
#include "Symbol.h"
class Message;
class Symbol;
class SharedEditor
{
private:
NetworkServer& _server;
int _siteId;
std::vector<Symbol> _symbols;
//other functions
public:
SharedEditor(NetworkServer ns);
~SharedEditor();
void process(const Message& m);
};
class NetworkServer:
#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include "SharedEditor.h"
#include "Message.h"
class SharedEditor;
class Message;
class NetworkServer
{
private:
std::vector<SharedEditor*> connected;
std::queue<Message> codaMessaggi;
public:
int connect(SharedEditor* sharedEditor);
void disconnect(SharedEditor* sharedEditor);
void send(const Message& m);
NetworkServer();
~NetworkServer();
};
You need to rework your various header files to break the dependency cycle.
The general rule is: if you only need pointers or references to a type T, you can get away with a forward declaration (class T;) instead of a full class declaration (class T { ... }, typically behind a #include).
For the example above I will go over each file and what you need:
Symbol.h needs a forward declaration of SharedEditor, as it only uses SharedEditor*.
Message.h needs a forward declaration of SharedEditor, but a full #include "Symbol.h" (compiler needs to know how big a Symbol is to calculate the size of Message)
SharedEditor needs a forward declaration of Message (passed as a reference), a full #include "NetworkServer.h" (passed as a parameter) and a full #include "Symbol.h" (used in a vector)
NetworkServer needs a forward declaration of SharedEditor (only used with pointers), but a full #include "Message.h" (used in a queue)
If you still have two classes that need full includes of each other, search stack overflow for "C++ dependency cycle" or somesuch.
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 4 years ago.
So I just began programming in c++ and I am planning to make a small game as my first project (with the SDL library).
So I have this really small piece of code in a header file that gives me an error that I can not solve.
main.h
#include "Screen.h"
#include "MainGame.h"
Screen* screen = nullptr; //main.h line 8
Screen.h
#pragma once
#include "SDL.h"
#include <string>
#include <stdio.h>
#include <iostream>
#include "GameState.h"
#include "Game.h"
using namespace std;
class Screen
{
public:
Screen(string name, int width, int height, GameState* state);
~Screen();
SDL_Window *window;
SDL_Surface *screen;
SDL_Renderer *renderer;
};
MainGame.h
#pragma once
#include "GameState.h"
#include <stdio.h>
class MainGame :
public GameState
{
public:
MainGame();
~MainGame();
void start();
void update();
void render();
void stop();
};
Game.h
#pragma once
#include "GameState.h"
#include "Screen.h"
#include "SDL.h"
#include "main.h"
class Game
{
public:
GameState* activestate;
Game(GameState state);
~Game();
void changeState(GameState newState);
bool isRunning;
void handleEvents();
void update();
void render();
void stop();
};
GameState.h
#pragma once
class GameState
{
public:
GameState();
~GameState();
virtual void start();
virtual void update();
virtual void stop();
virtual void render();
};
And it gives this errors:
Error C2143 syntax error: missing ';' before '* main.h 8
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int main.h 8
What do these errors mean and how do I solve them?
The error comes from your circular dependency. Some file includes Screen.h. Screen.h includes Game.h. Game.h includes main.h. main.h needs Screen.h but because of pragma once it can't include it. So it doesn't know class Screen. Either remove circular dependency (better solution if possible, here it's possible):
Remove #include "main.h" in Game.h
or use forward declaration:
Write class Screen; in main.h:7
I have structure: PrintChooseDlg.h
#ifndef PRINTCHOOSEDLG_H
#define PRINTCHOOSEDLG_H
#include <string>
#pragma once
#endif
class CPrintChooseDlg : public CDialog
{
public:
int choosing;
/*afx_msg void OnPrinter1();
afx_msg void OnPrinter2();*/
CPrintChooseDlg(CWnd* pParent = NULL);
enum { IDD = IDD_PRINTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
//afx_msg void OnPrinter1();
//afx_msg void OnPrinter2();
virtual void OnPrinter1();
virtual void OnPrinter2();
DECLARE_MESSAGE_MAP()
};
and PrintChooseDlg.cpp
// PrintChoose.cpp : implementation file
//
#include "stdafx.h"
#include "Tungsten.h"
#include "PrintChooseDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// PrintChoose
//IMPLEMENT_DYNAMIC(PrintChoose, CWnd)
CPrintChooseDlg::CPrintChooseDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPrintChooseDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CChooseLabelDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CPrintChooseDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CChooseLabelDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPrintChooseDlg, CDialog)
ON_BN_CLICKED(IDC_PRINTER1,OnPrinter1)
ON_BN_CLICKED(IDC_PRINTER2,OnPrinter2)
END_MESSAGE_MAP()
// PrintChoose message handlers
void CPrintChooseDlg::OnPrinter1()
{
choosing=0;
CDialog::OnPrinter1();
}
void CPrintChooseDlg::OnPrinter2()
{
choosing=1;
CDialog::OnPrinter2();
}
and in the main file where i am running from, i define the following headers:
#include "stdafx.h"
#include "Tungsten.h"
#include "TungstenDlg.h"
using namespace std;
#include<sstream>
#include <string>
The problem is i am always getting the following errors: error C2039: 'OnPrinter1': is not a member of 'CDialog'
error C2039: 'OnPrinter2': is not a member of 'CDialog'
What i tried is to add #include <string> at my header and make sure that the headers are not repeated, and defining Printer1 and Pronter 2 in the main file where i am running from, but i still get the same error. I appreciate your help. Thanks in Advance
To get the address of a member function, you need to use &CPrintChooseDlg::OnPrinter1.
Really old VC++, like VC6, didn't care about the correct syntax and generated incorrect message maps.
I'm not exactly sure why I'm getting these errors, I thought it was because I needed a forward declaration, but the problem still persists. I have no clue what is causing this. I put comments where the offending lines are. Looking for an explanation on why this is happening and a resolution. Thanks.
// Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include "Weapon.h"
#include "Monster.h"
#include <string>
// Forward declaration
class Race;
class Player
{
public:
Player();
/* Return Type Method Name */
bool IsDead();
std::string GetName();
int GetArmor();
void TakeDamage(int damage);
void CreateClass();
bool Attack(Monster& monster);
void LevelUp();
void Rest();
void ViewStats();
void Victory(int xp, Monster* monster);
void GameOver();
void DisplayHitPoints();
void SetRace();
private:
/* Type Name */
std::string m_Name;
std::string m_ClassName;
int m_Accuracy;
int m_HitPoints;
int m_MaxHitPoints;
int m_ExpPoints;
int m_NextLevelExp;
int m_Level;
int m_Armor;
int m_Gold;
Weapon m_Weapon;
Race m_Race; // problem: error C2079 uses undefined class 'Race'
};
#endif // PLAYER_H
An offending method with a cannot convert from 'Race' to 'int' error
void Player::SetRace()
{
Race race;
m_Race = race.SelectRace(); // problem: error C2440 cannot convert from 'Race' to int
}
Race class definition:
// Race.h
#ifndef RACE_H
#define RACE_H
#include <string>
class Race
{
public:
Race();
/* Return Type Method Name*/
Race SelectRace();
protected:
std::string GetName();
/* Type Name*/
std::string m_Name;
int m_Accuracy;
int m_HitPoints;
};
// ...below here implements multiple derived classes of type race
#endif // RACE_H
Yes, as you've found, a forward declaration is insufficient here. That's because there is a member of type Race in Player.
Include the whole header at the top of player.h:
#include "Weapon.h"
#include "Monster.h"
#include "Race.h"
Then the definition of your Race class will be visible to the definition of Player.
What is going on?
#include "MyClass.h"
class MyOtherClass {
public:
MyOtherClass();
~MyOtherClass();
MyClass myVar; //Unknown type Error
};
Suddenly when I include the .h and write that var Xcode gives me tons of errors... and also the unknown type error.
How can it be unknown when the .h is included right there?
Here is the NodeButton.h file which would correspond to the MyClass.h in the example
#pragma once
#include "cinder/Vector.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/Texture.h"
#include "cinder/Color.h"
#include "cinder/ImageIo.h"
#include "cinder/Timeline.h"
#include "cinder/app/AppBasic.h"
#include "cinder/App/App.h"
#include "Node.h"
#include "CursorMano.h"
using namespace ci;
using namespace ci::app;
using namespace std;
using namespace is;
typedef boost::shared_ptr<class NodeButton> NodeButtonRef;
class NodeButton : public Node2D
{
public:
NodeButton (CursorMano *cursor, string imageUrl, bool fadeIn = false, float delay = 0.0f);
virtual ~NodeButton ();
//methods
void update( double elapsed );
void draw();
void setup();
//events
bool mouseMove( ci::app::MouseEvent event );
//vars
CursorMano *mCursor;
gl::Texture mImageTexture;
Anim<float> mAlpha = 1.0f;
bool mSelected = false;
private:
};
And here are the contents of CursorMano.h which would correspond to MyOtherClass.h in the example.
#pragma once
#include <list>
#include <vector>
#include "cinder/app/AppBasic.h"
#include "cinder/qtime/QuickTime.h"
#include "cinder/gl/Texture.h"
#include "cinder/Vector.h"
#include "NodeButton.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class CursorMano {
public:
CursorMano (AppBasic *app);
~CursorMano ();
void mueveMano(Vec2i);
void update();
void draw();
void play(int button);
void reset(int button);
Vec2i mMousePos;
NodeButton mButtonCaller; //this gives the unknow type error
private:
AppBasic *mApp;
gl::Texture mFrameTexture;
qtime::MovieGl mMovie;
int mIdButton;
};
You have a circular dependency of your header files.
NodeButton.h defines NodeButton class which CursorMano.h needs to include so that compiler can see definition for NodeButton but NodeButton.h itself includes CursorMano.h.
You will need to use forward declarations to break this circular dependency.
In NodeButton.h you just use an pointer to CursorMano so You do not need to include the CursorMano.h just forward declare the class after the using namespace declarations.
using namespace std;
using namespace is;
class CursorMano;
It's probably a result of the circular dependency between you two header files (NodeButton includes CursorMano and CursorMano includes NodeButton). Try removing the #include "CursorMano.h" in NodeButton.h and add class CursorMano; before your NodeButton declaration.