This question already has answers here:
Cyclic dependency between header files
(4 answers)
Closed 9 years ago.
I have two header files. decimal.h and integer.h each containing their respective classes.
I want to write something like this.
//integer.h
#ifndef INTEGER_H
#define INTEGER_H
#include "decimal.h"
class Integer
{
...
operator Decimal();
}
#endif
//decimal.h
#ifndef DECIMAL_H
#define DECIMAL_H
#include "integer.h"
class Decimal
{
...
operator Integer();
}
#endif
What is giving me the trouble is that since they are including each over it behaves strangely in Visual Studio and an generate strange compiler errors. Is there any way around this?
Maybe you want just a forward declaration?
// In Integer.h
class Decimal;
class Integer
{
...
operator Decimal();
};
(You missed the last semicolon in your code, by the way.)
Related
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.
This question already has answers here:
How does #include work in C++?
(3 answers)
Closed 4 years ago.
For example:
In my.h file, I included nest1.h
#ifndef MY_H
#define MY_H
#include nest1.h
...
some_function_declaration
...
#endif
And in nest1.h, I included another h file nest2.h
#ifndef NEST1_H
#define NEST1_H
#include nest2.h
...
#endif
nest2.h
#ifndef NEST2_H
#define NEST2_H
int foo();
#endif
Will preprocessor copy foo() into my.h? Can I use foo() in my.cc file?
And if nest2.h included nest3.h, can my.cc use the functions in nest3.h? And why?
Please also link the relative articles if someone know the answer. Thank you!
Yes, includes work transitively.
You can include, recursively, [almost] as many headers as you want.
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
`
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.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C header file loops
Original Question:
I always had problems understanding why the following gives errors:
something.h
#ifndef SOMETHING_H
#define SOMETHING_H
#include "somethingelse.h"
#endif
somethingelse.h
#ifndef SOMETHINGELSE_H
#define SOMETHINGELSE_H
#include "something.h"
#endif
Why does this give errors?
1) SOMETHING_H is not defined
2) SOMETHING_H becomes defined, somethingelse.h get included
3) SOMETHINGELSE_H is not defined, becomes defined, and something.h gets included
4) SOMETHING_H is defined, jump to #endif, this should be the end of it?
EDIT:
turns out it doesn't give any errors at all. However the following does:
something.h
#pragma once
#include "somethingelse.h"
class something {
int y;
somethingelse b;
};
somethingelse.h
#pragma once
#include "something.h"
class somethingelse {
something b;
int x;
};
And it is logical, because the class 'something' is not yet defined when 'somethingelse' needs an instance of that class.
The problem is solved by forward definition:
something.h
#pragma once
class somethingelse;
class something {
int y;
somethingelse* pB; //note the pointer. Correct me if I'm wrong but I think it cannot be an object because the class is only declared, not defined.
};
in the .cpp, you can include "somethingelse.h", and make instances of the class.
Your description is exactly correct, except that there is no error at all. Add pragma message("Some text") (assuming Visual Studio) at various places to trace the flow.
As other posters have already noted, your header files most likely contain classes that mutually require each other's definition, and that is the cause of the problem. This sort of problem is usually solved by
Using forward references where possible
Moving #includes to CPP files where possible
That's exactly what happens.
This is called an "include guard" and is used to avoid infinitely recursive includes.