Why declare the class that you included as a header file? - c++

Why declare the class that you included as a header file?
#include "TreeCallObj.h"
#include "TreeDevObj.h"
#include "TreeDevCallObj.h"
class TreeCallObj; //what is the purpose of this line ?
class TreeDevObj; //what is the purpose of this line ?
class TreeDevCallObj; //what is the purpose of this line ?
class Apple
{
public:
...
private:
...
}

Consider this:
//a.h
#ifndef A_H
#define A_H
#include "b.h"
class A
{
B* b;
};
#endif
//b.h
#ifndef B_H
#define B_H
#include "a.h"
class B
{
A* a;
};
#endif
Now you try to include one of the files in a different one, say you #include "a.h".
The compiler will parse it as:
#ifndef A_H
#define A_H
fine - A_H isn't defined
#include "b.h"
try to paste the contents:
#ifndef B_H
#define B_H
ok, since B_H isn't defined
#include "a.h"
this will not define A, because A_H is defined. So next, we have
class B
{
A* a;
};
which will lead to an error, because A wasn't defined or declared before the use.
The forward declaration fixes this.
Of course, the best solution to this is to not include at all (unless you absolutely have to).

What is the purpose of this line?
Ideally nothing. It's superfluous.
However, as #Luchian Grigore pointed out, there may be such a badly-designed code that due to the incorrect use of include guards and cross-includes, the forward declarations may be necessary.

If in files there is definition of classes, so, forward declaration is unnecessary in normal cases.

No reason at all. You need to do one or the other, depending on the situation, but not both.

As it stands, there's no need.
However, this may have evolved historically: At some point, an incomplete type may have been enough:
class Foo;
struct Gizmo
{
void f(Foo);
};
Then, at a later point, the author decided she needed the complete type:
#include "Foo.hpp"
class Foo;
struct Gizmo
{
void f(Foo);
Foo x;
};
The original code may just have been amended with the now-necessary header inclusion...

I would guess there's some history to this. Orginally the coder tried not to include the header files and used forward declarations instead. Then as the code expanded they found they needed the header files after all, but didn't bother to deleted the forward declarations.
As others have said there's no purpose to having a forward declaration after the class declaration.

I notice that your header does not have guards against multiple inclusion. Also it is possible that some of the included other headers (headers usually have such guards) included that header back. As result it did not compile. So someone added forward declarations to fix the wrong bug.

If your header files are correct i see no point in declaring because they should already declared in header

Related

C++: Class C does not name a type (new scenario) 3 classes

first apologies if this is a repeated question, but I did research on this and also search a lot of existing threads, but haven't seen an answer. could you guys please put your thoughts on below?
//A.h
#ifndef A_H
#define A_H
class B;
class A
{
B * b;
};
#endif A_H
//B.h
#ifndef B_H
#define B_H
#include "A.h"
class B
{
A *a;
};
#endif B_H
//testerA.h
#ifndef A_H
#define A_H
#include "A.h"
class testerA
{
A *a; // GETTING ERROR A DOES NOT NAME A TYPE
};
#endif A_H
Now, I was wondering even if the forward declaration of class B is causing the issue,
but if I remove the forward declaration of B from A.h and any other references, I still get the issues, I am wondering am I doing some silly mistakes which other eyes might be able to catch?
EDITS:
ifndef are already declared.
The class A and B when compiled without the testerA work fine. but something's wrong with testerA.
Your include guards in testerA are wrong, replace them with:
#ifndef TESTER_A_H
#define TESTER_A_H
...
#endif
#ifndef tells the compiler to only read everything until the #endif, if the variable (in your case A_H) is not defined.
When your compiler copies testerA.h it defines A_H, so when it gets to read A.h, it does not read the content of the file at all. The result, is that the compiler does not find any definition for class testerA

Proper use of declaring objects in header files

I am working on a clock display assignment and my professor wants us to use two classes, NumberDisplay and ClockDisplay. So in total I have two header and three cpp files. When I implemented the first part of the assignment using just the first class everything was fine. I noticed though that my professor wants us to declare a NumberDisplay object inside our ClockDisplay header. I figured just declaring like normal would work like this NumberDisplay hours = NumberDisplay(24); however I am not able to access the information unless I include the NumberDisplay.h file for my ClockDisplay.h. When I do that however I am assuming my errors are due to using #include <NumberDisplay.h> in both my NumberDisplay.cpp and my ClockDisplay.cpp. I just would like to know the proper way to structure my files so that I can properly create NumberDisplay objects in my ClockDisplay header file and then use said objects in my ClockDisplay cpp file.
You can #include "NumberDisplay.h" within ClockDisplay.h. This will allow you to use NumberDisplay objects within your ClockDisplay's class declaration.
As a side note, be sure to use include guards for your headers. This will prevent the header from being included multiple times during compilation. Use #pragma once or
#ifndef NUMBERDISPLAY_H_
#define NUMBERDISPLAY_H_
...
#endif // NUMBERDISPLAY_H_
As user Sean Monroe pointed out about using header or include guards; this may not always be the full answer. This will help in many cases to fix your current problem but if you are not careful you can become a victim of circular includes.
Before I mention anything about that I will briefly describe the differences between #include <someheader.h> and #include "someheader.h". The first one will look where most of your system, os, and compiler and standard libraries files are located through the use of system environment variables that are setup by default through your IDE. The later will look in any immediate directories that are setup in the include paths for the current project with the root path being where the code lives when it is created if working in Visual Studio; other IDE's will more than likely be different, but the concept is still the same.
On circular includes: sometimes having header guards alone is not enough. Take for example:
file a.h
#ifndef A_H
#define A_H
#include "b.h"
class A {
private:
B b;
public:
explicit A( const B& b ) { ... }
};
#endif
file b.h
#ifndef B_H
#define B_H
#include "A.h"
class B {
public:
explicit( A* pA ) { ... }
};
#endif
Here this would generate a circular include and this is something that is very important to be aware of. Regardless of which class A or B you try to create an object of in some other file, namespace, class or function the compiler will try to construct the first class and in order to do so it needs to construct the second class however when trying to construct the second class to complete the first class it goes back and tries to construct the first class again since the next requires the first which is an incomplete object and visa versa. This is not exactly a circular include per say but it is a circular infinite recursion of dependencies of incomplete classes. You can read this Q/A for more information: Resolve Circular Dependencies.
Sometimes it is not enough to just include the appropriate header of one class into the header of another; sometimes you may need to just declare a class prototype and or forward declaration in a class's header then include the header file within that class's cpp file. But this will usually work most often with pointers or references but not local copies since pointers and references are addressed by memory location that have a fixed size in memory. Example:
file A.h
#ifndef A_H
#define A_H
class B;
class A {
private:
B* pB;
public:
explicit A( const B& b );
};
#endif
file A.cpp
#include "A.h"
#include "B.h"
A::A( const B& b ) { ... }
file B.h
#ifndef B_H
#define B_H
#include "A.h"
class B {
public:
B(){ ... }
/*param type*/ someFunc( A* pA ) { /* do something with pA */ }
};
There are more problems than what are discussed here but you can read about them in some of the other answers to the same link that I provided above.

Does #ifndef prevent circular reference compiler errors?

If every header uses #ifndef does this mean compiler errors regarding a circular dependency will not happen?
No, it does not.
It means the compiler won't try to include headers for infinity, but a circular dependency still poses a logical problem, because compilation is performed from top to bottom. Let's take a little look at why:
Source code
a.h
#ifndef A_H
#define A_H
#include "b.h"
struct A
{
B* ptr;
};
#endif
b.h
#ifndef B_H
#define B_H
#include "a.h"
struct B
{
A* ptr;
};
#endif
main.cpp
#include "a.h"
int main()
{
A a;
}
After preprocessor runs
The include guards enable us to actually run the preprocessor and have it finish its work in less-than-infinity time; so fast, actually, that I've done it by hand below. The result is:
struct B
{
A* ptr;
};
struct A
{
B* ptr;
};
int main()
{
A a;
}
The definition of B comes before the definition of A, so that A* ptr; cannot be understood. Sure, you can fix that, but only by reversing the order of inclusion, and then you have the opposite problem. Forward declarations and/or re-architecture are the only ways to resolve it.
Header guards solve a different problem. They do not allow you to simply do whatever you like.
It will not create any circular dependency, it will include the file multiple times as the name 'include' says. This usually happens when the code base is big and the we dont know if this file is already included by another header file.
We can also use a single statement , #pragma once

Making one header to be needed for several classes inclusion

I have a number of classes and they are quite close to each other like
class A
{
//code
};
class B
{
A* field;
//code
};
class C: public B
{
//code
};
And so on.
And I want to place them in a separate headers (A.h, B.h...) but to avoid adding every one of this header to projects I need a header like myLib.h, that will be just one needed header to include all the classes that I have wrote. Ho do I achieve it?
Also I think not to use #pragma once; and to make it working
#ifndef _MY_LIB_H
#define _MY_LIB_H
#endif
Where should I place it? In every header?
I've tried doing it like
class A;
class B;
...
in myLib.h
but then adding myLib.h to main.cpp is not enough to use A or B objects there. Also, in B.h that
#inlude myLib.h
void someMethod()
{
//field is instance of A
this.field.otherMethod();
}
causes an error because methods of A are declared in A.h, not in myLib.h.
Sorry for long and tangled question.
You should use a separate include guard in each of A.h, B.h, C.h:
// Note: not a good name for a guard macro (too short)
#ifndef _A_H
#define _A_H
// definition of A
#endif
And then MyLib.h becomes simply:
#include<A.h>
#include<B.h>
#include<C.h>
Of course each of your headers should manually include as many of the others as required so that it can stand alone (e.g. C.h would need to include B.h so that the code compiles if someone includes C.h directly).
In some cases you will not need to have one header include another because a forward declaration is enough -- for example in B.h, where an A* member is declared:
#ifndef _B_H
#define _B_H
class A;
class B
{
A* field;
};
#endif
Besides using the pattern
#ifndef _A_H
#define _A_H
... Stuffs
#endif
in each header, I always add
#ifndef _A_H
#include <A.h>
#endif
#ifndef _B_H
#include <B.h>
#endif
....
to other headers, like myLib.h. This considerably improves the speed of compilation because compiler does not need to load and scan the low level headers if they are already scanned.
I do not add this to my cpp files, because the number of headers in cpp is typically reasonable, while it mich more difficult to track relations between headers.

Circular dependencies in c++

Say I have these two classes:
// a.h
#include "b.h"
and:
// b.h
include "a.h"
I understand there is a problem over here, but how can I fix it and use a objects and their methods in b class and vice versa?
You can use forward declarations, like this:
class B;
class A
{
B* ThisIsValid;
}
class B
{
A SoIsThis;
}
For more information, see this SO question.
As for the preprocessor #includes, there's likely a better way to organize your code. Without the full story, though, it's hard to say.
To extend on #Borealid 's answer:
To avoid problems with circular includes, using an "include guard"
eg.
#ifndef MYFILE_H /* If this is not defined yet, it must be the first time
we include this file */
#define MYFILE_H // Mark this file as already included
// This only works if the symbol we are defining is unique.
// code goes here
#endif
You can use what is called a "forward declaration".
For a function, this would be something like void myFunction(int);. For a variable, it might look like extern int myVariable;. For a class, class MyClass;. These bodiless statements can be included before the actual code-bearing declarations, and provide the compiler with enough information to produce code making use of the declared types.
To avoid problems with circular includes, using an "include guard" - an #ifdef at the top of each header file which prevents it being included twice.
The "other" class can only have a reference or pointer to the "first" class.
in file a.h:
#include "b.h"
struct a {
b m_b;
};
in file b.h:
struct a;
struct b {
a* m_a;
};
void using_the_a_instance(b& theb);
in file b.cpp:
#include "b.h"
#include "a.h"
void using_the_a_instance(b& theb)
{
theb.m_a = new a();
}