Two-way inclusion of classes & template instances - c++

I'm having a problem when trying to compile these two classes (Army and General) in their own header files:
#ifndef ARMY_H
#define ARMY_H
#include "definitions.h"
#include "UnitBase.h"
#include "UnitList.h"
#include "General.h"
class Army
{
public:
Army(UnitList& list);
~Army(void);
UnitBase& operator[](const ushort offset);
const UnitBase& operator[](const ushort offset) const;
const uint getNumFightUnits() const;
const ushort getNumUnits() const;
const General<Warrior>* getWarrior() const;
private:
UnitBase** itsUnits;
uint itsNumFightUnits;
ushort itsNumUnits;
WarriorGeneral* itsGeneral;
};
#endif
and
#ifndef GENERAL_H
#define GENERAL_H
#include "generalbase.h"
#include "Warrior.h"
class Army;
template <class T>
class General : public GeneralBase, public T
{
public:
General(void);
~General(void);
void setArmy(Army& army);
const Army& getArmy() const;
private:
Army* itsArmy;
};
typedef General<Warrior> WarriorGeneral;
#endif
I have tried forward declaring WarriorGeneral in Army.h, but it doesn't seem to work, perhaps because it's a template instance? Anyway, the errors I'm getting with the above version are several of this kind and related problems:
Army.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
They're not even unresolved linker problems... Note I put the typedef of WarriorGeneral in the General.h file. I don't know whether this is correct. Is there anything that can be done to make this work?
Thanks in advance!

I can't tell what Army.h line 21 is because the one you posted doesn't have that many lines. The only thing I can see that's not declared in that header is UnitList. Is it properly forward-declared or have a header include you aren't showing us?
Do generalbase.h or Warrior.h include Army.h? If so, that would cause the seemingly circular includes. Try having it not do the include but forward declare Army instead.

You can "forward declare" a template with
template <class T> class General;

With that code (both cut and pasted into the same cpp file with the general bit where the #include is) there are no errors using g++, if you have these three defined instead of #include "generalbase":
struct GeneralBase { };
struct Warrior;
struct UnitList;
Without GeneralBase:
src/Army.cpp:13: error: expected class-name before ‘,’ token
Without Warrior:
src/Army.cpp:26: error: ‘Warrior’ was not declared in this scope
src/Army.cpp:26: error: template argument 1 is invalid
src/Army.cpp:26: error: invalid type in declaration before ‘;’ token
Without UnitList
src/Army.cpp:32: error: expected ‘)’ before ‘&’ token
So it's a bit hard to see which your error is; perhaps you have defined GENERAL_H by mistake and are not including it?

Yep, #Mark B. had it right! I removed Army.h from GeneralBase.h, and it now compiles perfectly. That makes me wonder, however, what happens if I need to include Army.h in GeneralBase...

Related

Errors when declaring multimap in function definition of C++ Class or just as a variable to use

I'm trying to use a function within a class, which has a multimap as a parameter but I always get an error - "Overloaded function not found in 'TdOpenGLGraphs'" and I don't understand why. I made sure it was all public so there are no permission issues, I've declared it in the class in the .h file and the .cpp file exactly the same (I even got intellisense to do it for me so there were no typos) and no luck. I've included the correct header too but i still get the error
I also get:
"missing type specifier = int assumed. Note C++ does not support default-int."
and "syntax error: missing ',' before '<'"
even if I just declare a multimap as part of the class.
In the Header file:
class TdOpenGLGraphs
{
public:
//TdOpenGLGraphs();
//~TdOpenGLGraphs();
//This is the problem function
void CreateGraph(int iCurrGraphID, const multimap<int, double>& mDataToDisp);
public:
//This also produces an error
//multimap<int, double>mCurrData;
};
The .cpp File
#include "pch.h"
#include "framework.h"
#include "TdOpenGLGraphs.h"
using namespace std;
void TdOpenGLGraphs::CreateGraph(int iCurrGraphID, const multimap<int, double>& mDataToDisp)
{
}
Have you included the map header in the .h file? Also, avoid the
using namespace std; part, rather write everywhere std::map etc.

"invalid use of incomplete type". Solving circular dependencies

I'm a newbie in C++ and I have been trying different suggestions from other questions but I can't make my code work.
I have a class "PChar" and another class "Action". An Action has two PChar members and a method of PChar ("act()") has to be able to create an Action object. So after trying different things I got this code:
"action.h":
#ifndef ACTION_H
#define ACTION_H
class PChar;
class Action
{
PChar *subject, *object;
public:
Action();
Action(PChar& p1, PChar& p2);
};
#endif
"action.cpp":
#include "action.h"
Action::Action(){};
Action::Action(PChar& p1,PChar& p2)
{
*subject=p1;
*object=p2;
};
"character.h"
#ifndef CHARACTER_H
#define CHARACTER_H
#include <string>
#include "action.h"
class PChar
{
public:
std::string name;
PChar();
PChar(std::string input_name);
void act(PChar& target, Action &action);
};
#endif
"character.cpp"
#include "character.h"
PChar::PChar(){}
PChar::PChar(std::string input_name)
{
name=input_name;
}
void PChar::act(PChar& target, Action& action)
{
action=Action(*this, target);
}
"main.cpp"
#include "action.h"
#include "character.h"
int main()
{
PChar char1("Joe");
PChar char2("Matt");
Action handshake;
char1.act(char2, handshake);
}
The goal is to create an object "handshake" which has both characters as members. When compiling I get the error:
action.cpp:7:10: error: invalid use of incomplete type ‘class PChar’
*subject=p1;
^
In file included from action.cpp:1:0:
action.h:4:7: note: forward declaration of ‘class PChar’
class PChar;
^
action.cpp:8:9: error: invalid use of incomplete type ‘class PChar’
*object=p2;
^
In file included from action.cpp:1:0:
action.h:4:7: note: forward declaration of ‘class PChar’
class PChar;
^
This is part of a larger project, that's why the files are structured like that, I just simplified the code to reproduce the error. I have tried solutions from other similar questions but they don't seem to work. Any help or tip is welcome. Thank you!
C++ needs to know the details of a type to be able to compile and assignment operation.
A solution is to include "Character.h" also in "Action.cpp".
You can forward declare type to declare pointer or reference to it. But when you start to use that type (declare it as a value or assign to it or call a method) it must be defined. Including character.h in action.cpp would solve compilation error. Note you have UB in your ctor:
Action::Action(PChar& p1,PChar& p2)
{
*subject=p1;
*object=p2;
}
as you dereference uninitialized pointers. You need to make them point somewhere, probably you meant to allocate dynamic memory. In that case std::unique_ptr would be preferrable as would solve issues with Rule of 3/5/0:
class Action
{
std::unique_ptr<PChar> subject, object;
public:
...
};
Action::Action(const PChar& p1, const PChar& p2) :
subject( new PChar(p1) ), object( new PChar(p2) )
{
}
and when you do not have intention to modify object you better pass it as const reference.

Class member attributes error

I have two classes and want to have a reference from class Kunde to class Konto and backward, but my compiler shows many errors. I don't know what the problem is. Please help me.
Class Konto:
#pragma once
#include "Kunde.h"
class Konto {
private:
Kunde* kunde;
protected:
int kontonummer;
double stand;
public:
int getKontonummer();
Kunde* getKunde();
double getKontostand();
bool einzahlen(double betrag);
virtual bool auszahlen(double betrag);
};
Class Kunde:
#pragma once
#include "Konto.h"
#include <string>
class Kunde {
private:
string vorname;
string nachname;
Konto* konto;
public:
Kunde(string vorname, string nachname);
void setKonto(Konto* konto);
Konto* getKonto();
};
I get following compiler errrors:
konto.h(6): error C2143: syntax error: missing ';' before '*'
konto.h(6): error C4430: missing typespecifier - int assumed. Note: C++ does not support "default-int"
konto.h(6): error C4430: missing typespecifier - int assumed. Note: C++ does not support "default-int"
and some more.
The header files can't include each other. Instead of the #includes, try a forward declaration in one or both, like this:
class Kunde;
You have a circular inclusion problem. You see the #pragma once statement in the first line of the header file? This prevents an inclusion of the header if it has already been included. Since your header files include each other, at the declaration of either Kunde or Konto the other one has not yet been defined.
You can circumvent the problem if you make a simple forward declaration of either class in the other header file. Specifically:
(Konto.h)
#pragma once
// Do NOT include Kunde.h
class Kunde;
class Konto {
// your further class definition as normal.
The only thing is that you now should include Kunde.h in the Konto.cpp, or else this would lead to a linker error.
EDIT: see comments :) thanks
Including one file in another that includes the first file, that includes the second file that includes the first file...
surely will confuse #pragma once
Konto is including Kunde.h and Kunde is including Konto.h. Do a forward declaration in both cases
This is a classic circular dependency. You can handle it a couple ways. The first is to use forward declarations for the other class you are trying to reference. You'll need to remove the include for the other class too.
class Konto;
class Kunde
{
Konto* konto;
...
};
The other way is to abstract out an interface that gives you what you want. I can go into further detail on that approach if you like.

unexplained syntax error defining threadpool inside class definition

I have the following class definition and for some reason I cannot define the threadpool inside the class definition itself. It says: syntax error: identifier 'numberofpoolthreads' I tried directly defining it in the class, but it gives me same syntax error, does anyone know why this is?
#include "stdafx.h"
#include <boost/threadpool.hpp>
#include <boost/threadpool/pool.hpp>
#include <boost/threadpool/detail/pool_core.hpp>
typedef boost::threadpool::fifo_pool resolverpool;
class ResolverThreadPoolManager
{
public:
ResolverThreadPoolManager::ResolverThreadPoolManager(int numberofpoolthreads);
ResolverThreadPoolManager::~ResolverThreadPoolManager();
resolverpool p(numberofpoolthreads);
private:
int numberofpoolthreads;
};
This line: resolverpool p(numberofpoolthreads); isn't valid in a class definition. You need a member variable, which you then initialise in the constructor. e.g.:
class ResolverThreadPoolManager
{
public:
explicit ResolverThreadPoolManager(int numberofpoolthreads);
...
private:
const resolverpool p;
};
ResolverThreadPoolManager::ResolverThreadPoolManager(int numberofpoolthreads)
: p(numberofpoolthreads)
{}
In your line
resolverpool p(numberofpoolthreads);
the argument "numberofpoolthreads" is not a type, so this is a malformed declaration. Perhaps
resolverpool p(int numberofpoolthreads);
? I imagine, perhaps incorrectly, that your error message also hints on which line the error occurred, which can help narrow down where in a file an error lies. (Although, typically only indicating "error is on this or some previous line.")

Syntax error missing ; before *

I have a header file like so:
#pragma once
#include "gamestate.h"
#include "ExitListener.h"
class InitialGameState : public GameState
{
public:
InitialGameState(Ogre::Camera *cam, Ogre::SceneManager *sceneMgr, OIS::Keyboard *keyboard, OIS::Mouse *mouse, Ogre::Root *root);
~InitialGameState(void);
virtual bool update(Ogre::Real time);
virtual void pause(void);
virtual void start(void);
void keyPressed(const OIS::KeyEvent &e);
void keyReleased(const OIS::KeyEvent &e);
//private:
ExitListener *mFrameListener;
};
The problem with this is that I get the following errors from VC 8:
InitialGameState.h(16) : error C2143: syntax error : missing ';' before '*'
InitialGameState.h(16) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
InitialGameState.h(16) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
(they all refer to the last line)
I have a class ExitListener.h which is why I don't get the errors
Edit: ExitListener.h:
#pragma once
#include <Ogre.h>
#include <OIS/OIS.h>
#include <CEGUI/CEGUI.h>
#include <OgreCEGUIRenderer.h>
#include "Thing.h"
#include "InitialGameState.h"
using namespace Ogre;
class ExitListener : public FrameListener, public OIS::KeyListener, public OIS::MouseListener
{
public:
ExitListener(OIS::Keyboard *keyboard, OIS::Mouse *mouse, Camera *cam, std::vector<Thing*> &vec):
mKeyboard(keyboard), r(0.09), mContinue(true), mRunningAnimation(false),
mMouse(mouse), mYaw(0), mPitch(0), things(vec), mCamera(cam), mWDown(false), mSDown(false), mADown(false),
mDDown(false)
{
things = vec;
mKeyboard->setEventCallback(this);
mMouse->setEventCallback(this);
}
bool frameStarted(const FrameEvent& evt);
bool keyPressed(const OIS::KeyEvent &e);
bool keyReleased(const OIS::KeyEvent &e);
bool mouseMoved(const OIS::MouseEvent &e);
bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id);
bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id);
void setOwner(GameState *g);
private:
AnimationState *mSwim;
Radian r;
Radian mYaw;
Radian mPitch;
OIS::Keyboard *mKeyboard;
OIS::Mouse *mMouse;
Camera *mCamera;
bool mContinue;
bool mRunningAnimation;
std::vector<Thing*> &things;
bool mWDown;
bool mADown;
bool mDDown;
bool mSDown;
GameState *mOwner;
};
Edit 2:
It turned out that the problem could be solved by a forward declaration and then including the other header directly in my .cpp file.
Thanks.
My guess is that ExitListener.h is including InitialGameState.h header file either directly or indirectly. So there is a circular dependency between the header file and compiler is unable to find the declaration for ExitListener. If you just need to store the pointer of ExitListener in this class then there is no need to include the ExitListener.h header file. Instead you can just use the forward declaration as class ExitListener;
EDIT: You can use the forward declaration as suggested above, or remove the InitialGameState.h include from ExitListener.h . You need to include GameState.h (the base class header file) only. But I prefer to use the forward declarations in header file and include the header file only in cpp.
The errors don't refer to the last line, but to the line before the last line. (Please be precise. If people know the compiler well which emits this error message, their guesses might be a lot better if they know the exact line it is given for.)
"ExitListener.h" is not a class, but a header. (This isn't Java.) One would assume that there is a class ExitListener defined (or at least declared) inside that header, but there could just as well be some other class, none at all, or many classes.
Without this header, it's impossible to say exactly what's wrong, although either circular dependencies between these two headers or a missing ; at the end of the ExitListener class' definition is a very good guess that fits my experience with such errors. At the very least I'm sure the error means that the compiler doesn't know what ExitListener is.
As others have said, you do not need a class definition in order to declare a pointer to that class, so (assuming that "ExitListener.h" defines the ExitListener class) you don't need to include the header at all. A simple forward declaration class ExitListener; is sufficient enough to declare the ExitListener *mFrameListener member. (You will need to include the full class definition in order to implement the InitialGameState member functions that deal with ExitListener, though. If you implement these functions in the header where InitialGameState is defined, you will need to keep that "ExitListener.h" include.)
Apparently the problem is with ExitListener definition, it's not considered valid at that point.
The error is in the ExitListener.h file (or any of the file it includes). Often this problem is due to a missing ; at the end of the class.
If you add the code of this file I will be able to help you further.
The problem
ExitListener was incorrectly declared. This is the only solution for VS to say this.
Check that there was no error when compiling the ExitListener class. (and that you did not forget the trailing ";")
A side note
Here you are using a pointer to ExitListener. You do not need to know the size or internal layout of ExitListener if you just declare a pointer.
A forward declaration would be enough.
I suspect you are missing the Ogre includes somewhere on your include chain.
My assumption is based on the little knowledge I have about your other header files and VC alerting that it's missing a type specifier: missing type specifier.