Header files and multiple class usage (EDIT: forward declarations) - c++

I have a problem where I have several header files, and I need to include each of them in each other. Obviously, this cannot be done, because when I compile, the error "include nested too deeply" is thrown - as this essentially asks the compiler to enter an infinite include loop.
I could fix it using void pointers, but this seems like bad coding practice to me.
Here is an example of what I am trying to do, to aid understanding:
File-A:
#include "File-B"
#include "File-C"
class A
{
public: B* p_B;
public: C* p_C;
};
File-B:
#include "File-A"
#include "File-C"
class B
{
public: A* p_A;
public: C* p_C;
};
File-C:
#include "File-B"
class C
{
public: B* p_B;
};
This just shows where each class declaration is needed. Surely there is a better solution to void*.
EDIT: I am already using include guards, this code is just to help you see what I am trying to do.

You should use include guards:
#ifndef _FILE_A_H_
#define _FILE_A_H_
// Contents of FileA.h...
#endif
Possibly, also use forward declarations to break cyclic dependencies between the definitions of your data structures.
In FileA.h:
class B; // No need to #include "FileB.h"
class A
{
public:
B* pB;
};
In FileB.h:
class A; // No need to #include "FileA.h"
class B
{
public:
A* pA;
};

If you are using pointers or references to the other classes, and no code in the header file, you can use forward declarations:
class A; // Forward declaration
class C; // Forward declaration
class B
{
public:
A* p_A;
C* p_C;
};
If code in the header file refers to any members of the other classes, you will have to include the entire definitions of the other classes.

I would use include guards, which only include a certain file once.
#ifndef FILE_A
#define FILE_A
class A
{
public: B* p_B;
public: C* p_C;
};
#endif
http://en.wikipedia.org/wiki/Include_guard
It only includes the header file once per file.
You can also use #pragma_once, although it is not standard.
In the case that doesn't work, you can use a forward declaration.
class B;
class C;
class A
{
public: B* p_B;
public: C* p_C;
};

This is why you have #include <> guards.
#ifndef _FILE_B
#define _FILE_B
#include "File-A"
#include "File-C"
class B
{
public: A* p_A;
public: C* p_C;
};
#endif

Related

How to resolve this header include loop?

Hi I already read similar questions about this topic, but I coudn't resolve my problem.
I think I have to do a forward declaration so I tried the following.
I have three classes A, B and InterfaceA
Defintion InterfaceA
#ifndef INTERFACE_A_H
#define INTERFACE_A_H
#include "B.h"
namespace Example
{
class B; // Forward declaration?
class InterfaceA
{
Example::B test;
};
}
#endif
Definiton class A
#ifndef A_H
#define A_H
#include "InterfaceA.h"
namespace Example
{
class A : public Example::InterfaceA
{
};
}
#endif
Defintion class B
#ifndef B_H
#define B_H
#include "A.h"
namespace Example
{
class A; // Forward declaration?
class B
{
Example::A test;
};
}
#endif
main
#include "A.h"
#include "B.h"
int main()
{
Example::A a;
Example::B b;
}
I get the following error in visual studio:
'Example::B::test' uses undefined class 'Example::A'
Edit:
Thank you so far, for all the help. It was very helpful. I think my problem was that I had a very poor design in my real project. I will change that.
Beside that I have now a better understanding for forward declarations :-)
If you really need that class A references class B and viceversa, instead of having instances of A and B as data members, consider using pointers, e.g. something like this:
// A.h
#pragma once
#include <memory> // for std::unique_ptr
// Forward declaration (A references B using pointer)
class B;
class A
{
...
std::unique_ptr<B> m_pB;
};
And similarly:
// B.h
#pragma once
#include <memory> // for std::unique_ptr
// Forward declaration (B references A using pointer)
class A
class B
{
...
std::unique_ptr<A> m_pA;
};
PS
Not related to the core of your question, however note that I used #pragma once instead of "old style" #ifndef/#define/#endif include guards; #pragma once seems simpler and clearer to me.
You are creating circular dependency. Revise your design.
Do you really need an instance of class A inside B and B inside A?
make them both inherit from the same parent header file, if they need to share header information.

C++ Can a class pass itself by reference?

Trying to pass a parent class object to a child class object so that the child class object has control over the parent class object's methods.
This is however resulting in header related issues.
I've tried forward declaring one of the classes but it seems whatever class is declared first always has trouble reading from the class declared below.
Both errors refer to Device' constructor where try to call dm's hello world method, they are:
Use of undefined type 'DeviceManager'
Left of '->HelloWorld' must point to class/struct/union/generic type
...
//main.cpp
#include "parent.h"
void main()
{
cout << "Created DeviceManager\n";
DeviceManager* deviceManager = 0;
deviceManager = new DeviceManager;
cout << "Giving DeviceManager a device\n";
deviceManager->p = new Device(deviceManager);
cout << "Giving Device a reference to DevicenManager\n";
deviceManager->Share();
}
...
class DeviceManager;
class Device
{
public:
Device(DeviceManager* manager)
{
dm = 0;
this->dm = manager;
this->dm->HelloWorld();
}
DeviceManager* dm;
};
//device manager
class DeviceManager
{
public:
DeviceManager()
{
p = 0;
}
void HelloWorld()
{
//if this calls we know the child has control over the parent.
cout << "Hello World";
}
Device* p;
};
Yes.
To solve circular dependencies with class member and function declarations, you can forward-declare a class:
class A;
class B {
A *a;
};
class A {
B *b;
};
To define class member functions that access members of the other class, you must define the function after the other class has been defined:
class B;
class A {
public:
void f(B &arg);
};
class B {
public:
void g(A &arg);
};
void A::f(B &arg) {
arg.g(*this);
}
void B::g(A &arg) {
arg.f(*this);
}
Usually, in a C++ project, you wouldn't even encounter this problem: You would put function definitions, i.e. implementations, into .cpp files, while putting the class definitions into header files. Class forward declarations, if neccesary, could be put into their own header files that are included by all headers that need them.
A full example of how you would split the above code into multiple files:
a.cpp
#include "a.h"
#include "b.h"
void A::f(B &arg) {
arg.g(*this);
}
b.cpp
#include "b.h"
#include "a.h"
void B::g(A &arg) {
arg.f(*this);
}
a.h
#ifndef _A_H_
#define _A_H_
#include "forward_declarations.h"
class A {
public:
void f(B &arg);
};
#endif //_A_H_
b.h
#ifndef _B_H_
#define _B_H_
#include "forward_declarations.h"
class B {
public:
void g(A &arg);
};
#endif //_B_H_
forward_declarations.h
#ifndef _FORWARD_DECLARATIONS_H_
#define _FORWARD_DECLARATIONS_H_
class A;
class B;
#endif //_FORWARD_DECLARATIONS_H_
As a general rule of thumb, if you need to forward-declare a class, you might have misdesigned something and should think about whether there is a better way (but there also are perfectly valid use cases that require class forward declarations).
If you don't understand my #ifndef, #define and #endif preprocessor lines: These are header guards, and should be used with all files that are included somewhere else, exception you know precisely what you're doing. Believe me. You'll regret ommiting one.
If your problem is cyclic dependancy, like this:
// DeviceManager.h
#include "device.h"
class DeviceManager
{
DeviceManager(Device& device) {}
};
// Device.h
#include "DeviceManager.h"
class Device
{
Device(DeviceManager& manager) {}
};
You can solve the problem be forward declaring one of the classes, and passing the object by pointer.
// Device.h
//#include "DeviceManager.h"
class DeviceManager;
class Device
{
Device(DeviceManager* manager) {}
};

Compilation issue - typedefs, forward declarations, namespaces?

I'm trying to help a coworker get something compiled - essentially, he was trying to reduce dependencies for a small executable we need to make from a larger software system.
I'm not sure I can fully explain the problem as I don't completely understand it... but I'm going to show what's going on here:
Library A: File: A.h
namespace CF {
typedef sometype B;
};
Library C: File C.h
//Forward declare Class
class CF::B;
Class D {
public:
B* UseB();
};
Library C: File C.cpp
#include "C.h"
#include "A.h"
using CF::B;
B* D::UseB()
{
return new B;
}
Sorry, I know this looks a little crazy but I have tried to simplify it from the set of files that we're actually dealing with.
We're typically getting either a multiple definition error on CF::B, or when we play with the code and change it around, sometimes in the CPP file it just doesn't recognize the type of CF::B.
I guess my first question is... can I forward declare the typedef like we've tried, or is there some other way to deal with the fact that B is a typedef in CF namespace, and we don't want it to be directly included in the C.h file?
This will probably help you:
a.h:
#ifndef NAMESPACE_A
#define NAMESPACE_A
namespace A
{
class B
{
public: int i;
};
}
#endif
c.h:
#ifndef NAMESPACE_A
#define NAMESPACE_A
namespace A
{
class B;
}
#endif
class D
{
public:
A::B* UseB();
};
main.cpp:
#include "a.h"
#include "c.h"
using A::B;
B* D::UseB()
{
return new B();
}
int main(int argc, char* argv[])
{
D* d = new D();
B* b = d->UseB();
b->i = 1;
return 0;
}
... works fine for me ;)
A forward declaration would be more like
namespace CF { class B; }
The compiler cannot make anything out of CF::B unless it already knows CF to be a namespace.
You also cannot forward declare a typedef, because the compiler must know if B is a class or a built in type. Some built in types have special rules, like char* or void*.

C++ Class instantiation problem

I have included the proper
Header Files ,
Header Gard
but i cannot instantiate a specific class
Getting Error
error C2065: 'ClassName' : undeclared identifier
Sample Code
Class A{
//instantiate class B
}
Class B {
//need to instantiate Class A
}
Since you haven't posted any real code for us to actually make use of, I'll take a guess as to what your code actually looks like:
A.h:
#ifndef HEADER_A
#define HEADER_A
#include "B.h"
class A {
private:
B someMember;
};
B.h:
#ifndef HEADER_B
#define HEADER_B
#include "A.h"
class B {
public:
doSomething(A param);
};
B.cpp:
#include "B.h"
#include "A.h"
void B::doSomething(A param) { }
As Flinsch said, you need to have forward declarations to avoid problems with include ordering. The simplest way is to get rid of the circular includes in the .h files and just include the forward declarations (class B; and class A; into A.h and B.h) instead.
btw. you don't have ; at the end of class definition.
Under my understanding there is a circular dependency between classes A and B. So you need to use forward declaration for at least one of those two classes (or even both).

Two classes and inline functions

I have two classes and both of them uses some of the other class, on example:
// class1.h
class Class1;
#include "class2.h"
class Class1 {
public:
static Class2 *C2;
...
};
// class2.h
class Class2;
#include "class1.h"
class Class2 {
public:
static Class1 *C1;
...
};
And when I define it like in example above, it works (I also have some #ifndef to avoid infinite header recurency). But I also want to add some inline functions to my classes. And I read here that I should put definition of inline function in header file, because it won't work if I'll put them in cpp file and want to call them from other cpp file (when I do it I get undefined reference during linking). But the problem here is with something like this:
// class1.h
...
inline void Class1::Foo() {
C2->Bar();
}
I get error: invalid use of incomplete type ‘struct Class2’.
So how can I do it?
You need to delay including the header, but then include it and define your inline methods. By doing this in each header, they are self-sufficient and including one will always include the other, with include guards preventing infinite recursion.
A.hpp
#ifndef INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD
#define INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD
struct B;
struct A {
B* p;
void foo();
};
#include "B.hpp"
inline
void A::foo() {
if (p) p->bar();
}
#endif
B.hpp
#ifndef INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8
#define INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8
struct A;
struct B {
A* p;
void bar();
};
#include "A.hpp"
inline
void B::bar() {
if (p) p->foo();
}
#endif
You have it mix'd up. What you want is:
// class1.h
class Class2;
class Class1 {
public:
static Class2 *C2;
...
};
// class2.h
class Class1;
class Class2 {
public:
static Class1 *C1;
...
};
And include the respective headers in the source. The line:
class Class1; // or Class2
Declares an incomplete type, and you can have pointers and references to incomplete types. Upon usage, though, it needs to be complete. So just say "hey it'll exist!" in the header, and in the source tell it what it is.
My suggestion is that you place common methods and members into a base class, then derive C1 and C2 from the base class. This may fix the circular dependency issue.