Forward Declaration issue [duplicate] - c++

This question already has answers here:
How are circular #includes resolved?
(4 answers)
Why aren't my include guards preventing recursive inclusion and multiple symbol definitions?
(3 answers)
Closed 9 years ago.
I currently ran into a situation which I do not understand and would appreciate it if someone could explain to me why this is happening and how I may resolve it.
Suppose I have two header files Client.h and Order.h with classes Client and Order respectively.This is an overview
FileName: Order.h
#ifndef Order_Header
#define Order_Header
.....
#include "Client.h"
class Order
{
public:
enum OrderType{open,close};
Client db; // ---> Line A
};
#endif
FileName: Client.h
#ifndef Client_Header
#define Client_Header
.....
#include "Order.h"
class Client
{
public:
void someMethod(Order::OrderType e);
};
#endif
Now if this project is compiled I get an error at line A saying it does not recognize the Client Class. However If I move the enum from the Order Class to the Client class
such that the enum is accessed using Client::OrderType then I get no errors. What is happening here any suggestions on how I can resolve this arent my header guards working ?

You have an circular dependency between client and order. Its best to try to avoid it. But if you need it you can forward declare your classes (and templates) and use references and pointers to them. The classes can not be used because they are incomplete.
#ifndef Order_Header
#define Order_Header
class Client; // forward declaration
class Order
{
public:
enum OrderType{open,close};
// the following declarations work:
Client* db_1;
Client& db_2;
std::shared_ptr<Client> db_3;
// the following declaration does not work, because of incomplete type
Client db_4;
};
#endif
The same with Client.h. You should note that the declaration of your methods have to be changed from passing Client to Client const& as you cant use the incomplite type Client in your interface. Client&, Client*, std::shared_ptr<Client> and variations are complete types.
In your implementation files you can include all headers and your types are complete and you can work with them.

It's beacause when the compile the Order.h file he go first to the #include "Client.h" the it's compil it before Order.h and when he arrive to void someMethod(Order::OrderType e); Order is not defined. To solve it try
#ifndef Order_Header
#define Order_Header
.....
// #include "Client.h" Put it only on your cpp file
Class Client;
Class Order
{
public:
enum OrderType{open,close};
Client db; ---> Line A
}
#endif
FileName: Client.h
#ifndef Client_Header
#define Client_Header
.....
#include "Order.h"
Class Client
{
public:
void someMethod(Order::OrderType e);
}
#endif
`

Related

How do I create two classes that refer to each other in different header files? [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 1 year ago.
I have two classes in two different header files. I, as advised in another topic with a similar question, declared class A before class B and declared class B before class A. But it did not help. Seller still can't see the Organization
Seller.h
#ifndef OOP_3_SELLER_H
#define OOP_3_SELLER_H
#include "Organization.h"
class Organization;
class Seller{
protected:
Organization*owner;
...
};
Organiztion.h
#ifndef ORGANIZATION_OOP3_H
#define ORGANIZATION_OOP3_H
#include "Seller.h"
class Seller;
class Organization{
std::vector<Seller*> own;
...
};
The compiler tells me the following error:
error C2027: use of undefined type 'Organization'. That is, as I understand it, the Organization sees the Seller, but the Seller does not see the Srganization
Since you've forward declared the class Organization in Seller.h there is no need to write #include "Organisation.h". Similarly, in Organization.h" since you've forward declared class Seller there is no need to write #include "Seller.h". Also, always take into account cyclic dependency like in your program Organization.h has a #include "Seller.h" and then Seller.h has a #include "Organization.h"
The running(successfully compiled) program can be seen here.
Organization.h
#ifndef ORGANIZATION_OOP3_H
#define ORGANIZATION_OOP3_H
//#include "Seller.h"
#include <vector>
class Seller;
class Organization{
std::vector<Seller*> own;
};
#endif
Seller.h
#ifndef OOP_3_SELLER_H
#define OOP_3_SELLER_H
//#include "Organization.h"
class Organization;
class Seller{
protected:
Organization*owner;
};
#endif
In the .cpp files(also called source files) you should include the headers using #include.
Your program has other problems too like many(and i mean many many)of the methods in Seller.h have no return value for methods that have non-void return type.
I tried solving some of the problems in you github code but there are just too many problems(errors and warnings) to solve. Also i would suggest you to use cpp files as well.

(Redefinition error) Create multiple inherting classes from one baseclass in C++

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

Header file imports acting strangely [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Circular dependencies with headers. Using #ifndef and #define
I try to import a header file that contains a class that extends to class in that header file and it doesn't work :S
TileGrass.h:
#ifndef TILEGRASS_H_
#define TILEGRASS_H_
#include "Tile.h"
class TileGrass : public Tile
{
public:
TileGrass(unsigned char);
};
#endif /* TILEGRASS_H_ */
Tile.h:
#ifndef TILE_H_
#define TILE_H_
class Tile
{
public:
Tile(unsigned char);
unsigned char id;
};
#include "TileGrass.h"
extern Tile* tiles[256];
TileGrass tileGrass = TileGrass(0);
#endif /* TILE_H_ */
Doing this gives me the error:
error: 'TileGrass' does not name a type
At a first glance, I see two errors:
a circular include which isn't necessary (Tile.h doesn't need to include TileGrass.h - you can just re-organize the file to remove the include)
TileGrass tileGrass = TileGrass(0); is a definition, and it's in a header, so you'll get a multiple definition error if you include the header multiple times. If you want a global (rethink that), you have to use extern.

c++ how to include (circular dependency)?

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

Error while trying to use class in another class

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