I'm using Visual Studio 2008 Express edition, and keep getting the following error:
"Cascadedisplay.h(4) : fatal error C1014: too many include files : depth = 1024.
Obviously I'm doing something very wrong with include files, but I just can't see what.
Basically, I have an interface class, StackDisplay, from which I want to derive CascadeDisplay in another file:
#if !defined __BASE_STACK_DISPLAY_H__
#define __BASE_STACK_DISPAY_H__
#include <boost\shared_ptr.hpp>
#include "CascadeDisplay.h"
namespace Sol
{
class StackDisplay
{
public:
virtual ~StackDisplay();
static boost::shared_ptr<StackDisplay>
make_cascade_display(boost::shared_ptr<int> csptr)
{
return boost::shared_ptr<StackDisplay>(new CascadeDisplay(csptr));
}
};
}
#endif
and then in CascadeDisplay.h:
#if !defined __CASCADE_DISPLAY_H__
#define __CASCADE_DISPAY_H__
#include "StackDisplay.h"
#include <boost\shared_ptr.hpp>
namespace Sol
{
class CascadeDisplay: public StackDisplay
{
public:
CascadeDisplay(boost::shared_ptr<int> csptr){};
};
}
#endif
So what's up with that?
#if !defined __CASCADE_DISPLAY_H__
#define __CASCADE_DISPAY_H__
Second line should be:
#define __CASCADE_DISPLAY_H__
Same with:
#if !defined __BASE_STACK_DISPLAY_H__
#define __BASE_STACK_DISPAY_H__
Also, names that contain a double-underscore are reserved for the implementation, you are not allowed to create such names in your own code. Same goes for names that begin with a single underscore and an uppercase letter.
There is a typo in your guards
#if !defined __CASCADE_DISPLAY_H__ <--- here you have DISPLAY
#define __CASCADE_DISPAY_H__ <--- here you have DISPAY (no L!)
and yes, avoid double underscores in such names
Is #if !defined... legit? I always used #ifndef.
Either way, why does your "base" class require the reference to CascadeDisplay? That doesn't seem right. Consider replacing your call to create a new CascadeDisplay with a call to a pure virtual function in StackDisplay that your subclass must implement appropriately.
IE, something like (and forgive, I don't have a c++ compiler handy to check this):
namespace Sol
{
class StackDisplay
{
public:
virtual ~StackDisplay();
boost::shared_ptr<StackDisplay>
make_cascade_display(boost::shared_ptr<int> csptr)
{
return make_display(csptr);
}
protected:
virtual boost::shared_ptr<StackDisplay> make_display(boost::shared_ptr<int> csptr) = 0;
};
class CascadeDisplay: public StackDisplay
{
public:
CascadeDisplay(boost::shared_ptr<int> csptr){};
protected:
virtual boost::shared_ptr<StackDisplay> make_display(boost::shared_ptr<int> csptr)
{
return new CascadeDisplay(csptr);
}
};
}
I believe this solution is superior, in general, to the forward declaration because you're eliminating some tight coupling between your superclass and your subclass, and making a more generic interface besides. This lets you eliminate the #include of CascadeDisplay.h in StackDisplay.h.
Related
Greetings oh mighty coders,
I am a beginner and in a bit of trouble here.
There is my baseclass (sensor.h):
class sensor
{
private:
int sensor_id;
string sensor_name;
string sensor_type;
float reading;
public:
sensor();
sensor(int, char*, char*);
~sensor();
/* Few extra methods here */
};
... and I want to create 4 other classes that inherit from my baseclass sensor
(temperaturesensor, humiditysensor... and so on).
#include "sensor.h"
class temperaturesensor:public sensor
{
public:
Temperatursensor(int, char*,char*);
~Temperatursensor();
/* Few extra methods here */
};
Thing is: Every single one of these classes has to be in its own .cpp/.h file and then be included and used in my main.cpp.
using namespace std;
#include <xyz.h>
/* Other libaries here */
....
#include "temperaturesensor.h"
#include "humiditysensor.h"
int main()
{
sensor* station[2];
station [0] = new temperaturesensor(x,y,z);
station [1] = new humiditysensor(x,y,z);
}
If I include one of them it's no biggie. However: If I use multiple ones I get an redefinition error.
error C2011: 'sensor': 'class' typeredefinition
c:\users\name\desktop\project\sensor.h 14
error c2011: 'temperaturesensor' : 'class' typeredefinition
What can I do to workaround this? Note that I am not allowed to use #pragma once
Sorry for my stupidity and thanks in advance!
You must use:
#ifndef FILE_H
#define FILE_H
.. normal code here
#endif
or
#pragma once
but too, I think, that sensor schould be abstract class and you schould use virtual destructor.
One more think is that array is numerate from 0.
you forgot to use the include guards in your header class,
this is redefining your base class everytime you use it.
so, just do a
#pragma once
or a normal include guard
#ifndef YOURFILENAME_H
#define YOURFILENAME_H
.. normal code here
#endif
Then you will not have the multiple definition error.
The definition of the class sensor is coming from both "temperaturesensor.h"
and "humiditysensor.h". Use guards https://en.wikipedia.org/wiki/Include_guard or #pragma once: https://en.wikipedia.org/wiki/Pragma_once
I have to get a project done for university but I can not figure out how it can be done.
The problem is that I want to allocate a Condition object (not a Pointer) in the GameHandler Class like in the example below, but I can not do this because I think of the included Condition.h in the Engine Class. So I am not able to include the Condition class twice. Am I wright?
What can I do to get a solution that works kind like my wrong example?
Thank you a lot!!!
Condition.h:
#ifndef CONDITION_h
#define CONDITION_h
class Condition
{
enum Rank {FIRST, SECOND, THIRD};
void doSomething();
};
#endif
Engine.h
#ifndef ENGINE_h
#define ENGINE_h
#include "Condition.h"
class Engine
{
Condition::Rank getter();
};
#endif
But now I have a third Class which should look like this where I want to create a Condition Object (not a Pointer). How can this be done?
GameHandler.h
#ifndef GAMEHANDLER_h
#define GAMEHANDLER_h
#include "Condition.h"
class GameHandler
{
Condition condition_;
condition_.doSomething();
}
#endif
By default, class members are private in C++ (more about access specifiers here). Try declaring them as public.
class Condition
{
public:
enum Rank {FIRST, SECOND, THIRD};
void doSomething();
};
Also, you cannot call a method within the declaration of a class! You'd have to do it inside a method (for example, the constructor), but the where will depend on what do you want to do.
class GameHandler
{
Condition condition_;
public:
GameHandler() {
condition_.doSomething();
}
}
Using :
#ifndef GAMEHANDLER_h
#define GAMEHANDLER_h
/.../
#endif
Will prevent multiple inclusion, so it doesn't matter if you include your header multiple times
I'm new to C++ abstract classes and I'm trying to learn how to work with it. So I started by defining an abstract class with only pure functions, let's call this class SceneObj, so far so good. Afterwards, I start by defining a new abstract class that I'm calling IScreen; this new Class is, also, another abstract class, but it add new requirements.
Unfortunately when trying to compile this simple code I ran into the following error: error C2011: 'IScreen' : 'class' type redefinition.
I'm using Visual Studio 2012 and the code that I'm trying to compile is the following:
#include <stdlib.h>
using namespace std;
class SceneObj
{
protected:
float center;
public:
virtual void SetCenter(float,float,float) = 0;
virtual void SetCenter(float) = 0;
virtual float GetCenter() = 0;
virtual ~SceneObj();
};
class IScreen : public SceneObj
{
public:
virtual void SetCenter(float,float,float) = 0;
virtual void SetCenter(float) = 0;
virtual float GetCenter() = 0;
virtual float GetStartCorner() = 0;
virtual void SetSize(float,float) = 0;
virtual void SetSize(long) = 0;
virtual long GetSize() = 0;
virtual ~IScreen();
};
Could someone point me what/where is the flaw in this code?
edit: Changed code to a minimal one
edit2: This is in a header file and apparently if i change it to a .cpp it compiles without problems. But I needed/wanted to declare my class in headers and then define then in .cpp.
C++programs also use the preprocessor to define header guards. Header guards
rely on preprocessor variables. Preprocessor variables have one of two
possible states: defined or not defined. The #define directive takes a name and defines
that name as a preprocessor variable. There are two other directives that test whether
a given preprocessor variable has or has not been defined: #ifdef is true if the variable
has been defined, and #ifndef is true if the variable has not been defined. If the test is
true, then everything following the #ifdef or #ifndefis processed up to the
matching #endif.
We can use these facilities to guard against multiple inclusion as follows:
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
struct Sales_data {
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
#endif //SALES_DATA_H
For instance, in the header file you will find something LIKE the follwing:
#ifndef __*__SceneObj
#define __*__SceneObj__
//Place the abstract class here
#endif
So you have to put the abstract class in between the #define and the #endif. (This is the definition the compiler will consider). you simply don't have these etiquettes on the cpp file. That is why it works there.
Additionally try to have one class per header file, so do not declare the child class on the same header file.
It means that somewhere you already have defined type IScreen. Usually the compiler gives a reference to the duplicated definition.
So investigate the error message.
As for you code snippet then it is irrelevant.
MS VS usually gives several messages if it found an error.
Another reason can be that you included the cpp module with member function definitions in the module with main.
For example
Header file: header.h
#include <stdlib.h>
using namespace std;
class SceneObj
{
//...
};
class IScreen : public SceneObj
{
//...
};
cpp module with member function definitions: module,cpp
#include "header.h"
//...
module with main
#include "header.h"
#include "module.cpp"
//...
Also include directive
#pragma once
in your header file.
I have Environment.h file:
#include <windows.h>
#include "interfaces.h"
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
class Environment {};
#endif
and i have Interfaces.h file:
#ifndef INTERFACES_H
#define INTERFACES_H
class IMoving {
public:
virtual void Move() = 0;
};
#endif
in interface IMoving i would like to get an Environment class, to know how to move
class IMoving {
public:
virtual void Move(Environment*) = 0;
};
if i want to do this i need to include environment.h
#include "Environment.h"
and here i'm getting an error, becouse Environment.h - includes Interfaces.h and Interfaces.h - includes Environtment.h. So how to make it work ?
Sorry for spelling mistakes
For circular dependencies one can use Forward declaration(s)
In Interfaces.h just above interface definition, forward declare Environment as follows:
class Environment;
Then when you implement IMoving in a class, you will include Environment.h in its implementation (cpp) file.
You can read more about Forward declaration here.
It looks like you misspelled the class name a few times (Environtment,Envrirontment). Could that be the origin of your issue?
Otherwise I typically use the Forwarded Declaration
I'm writing something in C++. I have 2 classes which I want to contain one into the other as in the folowing (these are just the header files):
//Timing.h
#ifndef _Timing_h
#define _Timing_h
#include "Agent.h"
class Timing{
private:
typedef struct Message{
Agent* _agent; //i get here a compilation problem
double _id;
} Message;
typedef struct MessageArr{
} MessageArr;
public:
Timing();
~Timing();
};
#endif
//Agent.h
#ifndef _Agent_h
#define _Agent_h
#include <string>
#include "Timing.h"
using namespace std;
class Agent{
public:
Agent(string agentName);
void SetNextAgent(Agent* nextAgent);
Agent* GetNextAgent();
void SendMessage(Agent* toAgent, double id);
void RecieveMessage(double val);
~Agent();
private:
string _agentName;
double _pID;
double _mID;
Agent* _nextAgent;
};
#endif
The compilation error is in the Timing.h file inside the definition of the struct:
expected ';' before '*' token
What am I doing wrong?
Try not to include "Agent.h" in Timing.h but include a forward reference instead:
#ifndef _Timing_h
#define _Timing_h
class Agent;
class Timing{
private:
typedef struct Message{
Agent* _agent; //I get here a compilation problem
double _id;
}Message;
typedef struct MessageArr{
}MessageArr;
public:
Timing();
~Timing();
};
#endif
You can include Agent.h in the timing.cpp file.
This way you remove the circular reference and you reduce the coupling between the classes.
Since you don't use the class Timing in your class Agent, you can remove this include as well (but this might be a copy mistake from your shortened example).
Basically - whenever you need either the size of an object or some of it's functionality, you must include its header file. If you don't need it (e.g. if you use only pointers to this object or references), you should not. This reduces compile time (especially for large projects)
For the 1 instance problem - check your favorite design patterns book (e.g. the GoF). The singleton pattern might be what you need.
Rule of thumb.
Do not include other header files from your header files if you don't need to.
Pre-Compiled header file stuff being a notable exception.
If your class only depends on a pointer or a reference you do not need the header file:
Use forward declaration in this situation.
In the source file include only the header files you need to make it work
Include them from most specific to least specific.
This will prevent the problem of hiding a dependency.
Other notes:
Do not use Underscore followed by a capitol letter.
This is reserved for the implementation. see
As in #define _Timing_h
Also note it is traditional that macros are all upper case.
Do not put using namespace X; in a header file
If you do this you pollute the namespace for everybody that uses your header file.
This is a real easy way to PO other developers who now have to re-factor their code to make sure it does not use any of a bunch of new classes/functions/templates that are suddenly being resolved against that was not there before.
So try this:
Timing.h
#ifndef TIMING_H
#define TIMING_H
class Agent;
class Timing{
// STUFF
};
#endif
Agent.h
#ifndef AGENT_H
#define AGENT_H
#include <string>
class Agent{
// STUFF
};
#endif
Timing.cpp
#include "Timing.h"
#include "Agent.h"
// STUFF
Agent.h
#include "Agent.h"
using std::string; // Bring as little as possable into the the global namespace.
// prefer to prefix all cases with std::
// STUFF.
You can't have circular includes.
Stop including "Timing.h" from "Agent.h", since it's not needed there.
Also, you don't need to have the "Agent.h" included in "Timing.h" either, just use a forward reference:
class Agent;
This makes it possible to have pointers to something called Agent.
You need to add the forward declaration of Agent in Timing.h
// Timing.h
#ifndef _Timing_h
#define _Timing_h
class Agent; // fwd declaration.
class Timing{
private:
typedef struct Message{
Agent* _agent; // without fwd decln Agent type is unknown here.
// rest all same.
EDIT:
As suggested by others, you should not be including Agent.h in Timing.h