C++ header inclusions - c++

Hello I'm new to C++ so bear with me, I'm making a header for a class and I just want to know if I plan on making an object from another class in this one should I include that in the header? for example
class myClass1{
public:
"constructor and methods here"
private:
OtherClass oc;
"other variables here"
};
I know this is a pretty simple question but I can't seem to find the answer anywhere. Any help would be appreciated!

Since as you say that you are new at C++, this might seem a bit overkill for your immediate needs. Keep in mind what I'm trying to teach you is not how to hack this thing up right now, but good coding skills that will transfer to future projects and real work.
A stretch goal, and a general rule of thumb that I would recommend is:
In a header file, #include nothing, or as close to nothing as is
possible.
Why? There are at least two reasons.
First, it keeps compiles fast. This is nice, but not the real reason. The real reason is:
Second, it reduces interdependence between modules and hard couplings. An interdependence between modules is an easy thing to create, and a very difficult thing to break when it becomes a problem.
Contrary to the other answers posted here, no, you do not need to #include OtherClass's header file in this header file. This assertion yields two questions:
How is it possible to not include the header?
Why would you not include the header, even if it is possible not to?
In order:
The header file doesn't need to know anything about the definition of OtherClass. Only the translation unit does. The TU needs to know the definition of OtherClass before it can define MyClass1, but that is handled simply. Consider:
OtherClass.h:
#ifndef OTHERCLASS_H
#define OTHERCLASS_H
class OtherClass
{
};
#endif
MyClass.h:
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
public:
OtherClass mOC;
};
#endif
main.cpp:
#include <cstdlib>
#include "OtherClass.h"
#include "MyClass.h"
int main()
{
MyClass mc;
}
The Translation Unit here is main.cpp and everything it #includes. The whole package. Since you do not compile header files directly (eg by themselves), headers are not translation units.
I suggest that what I propose above is better than adding:
#include "OtherClass.h"
to MyClass.h because it reduces the interdependence between the two objects.
This obviously isn't a concern right now, or in a toy program such as this. It becomes an issue later, in large & complicated codebases when you try to make changes to underlying classes. At those times, breaking these interdependancies becomes exceedingly difficult and maybe impossible depending on how much forethought you have given your design. This becomes a lesson learned with great difficulty.

Yes. If oc was a pointer or a reference, then you could get by with just a forward declaration (which appears above the class statement):
class OtherClass;
class myClass1 {
...
The include statement is needed because the compiler needs to know the details of OtherClass to define myClass1.

Yes include using #include "OtherClass.h". If you were using a system header or maybe something from STL, you would use: #include <SomeSystemHeader>

Related

Can I put `extern template` into a header file?

Is putting an extern template in a header file and then do the explicit template instantiation in a unit compilation file valid ?
For example in the compiling example for g++, is this working to avoid the instancation of nothing<int> twice ? Why doesn't anybody write it like this and prefer to copy pase the extern template line in each .cpp file ?
A.hpp:
#ifndef HEADERC_A
#define HEADERC_A
template< typename T > struct nothing {};
extern template struct nothing<int>;
#endif
A.cpp:
#include "A.hpp"
template struct nothing<int>;
main.cpp:
#include "A.hpp"
#include <iostream>
int main()
{
nothing<int> n;
return 0;
}
Well, this is certainly "valid" insofar as gcc will compile this, and do pretty much what you expect to happen.
As far as why doesn't everyone to do this, well, once you go beyond a trivial situation like this, and you start managing a large collection of widely used templates, it will quickly reach the point where it simply becomes not practical to keep track of every parameter that each one of your templates gets used with, so that it can be instantiated explicitly, in this manner.
It's going to be much easier for the compiler to keep track of it, for you.
As previously stated this is a perfectly valid use case and if it fits your programming model then you should use it. But buyer beware:
There are several reasons why extern templates are not commonly declared in header files and then explicitly instantiated in the cpp files.
A very common model for implementing template classes/functions is to place the definitions in the header file and the implementation in an "inl" or other named file. But then include that file at the bottom of the header file. There are reams of code that use this approach to resolving the template/header/implementation separation problem. Putting an "extern" at the top of the implementation makes the code much easier to read and maintain, especially when multiple classes get involved. Heres an example:
A.hpp
#pragma once
template< typename T > struct nothing {
void donothing(T input); // fastest func around
};
#include "A.inl"
A.inl
// does NOT include A.hpp
extern template struct nothing<int>; // save time and space
template<typename T> nothing<T>::donothing { return; }
Instance.h
#include "A.hpp"
template struct nothing<int>; // compiler generates code now
But there is a hidden caveat in all this...
If this gets implemented as you suggest then what happens when another person comes along and wants:
nothing<float> mynothing;
The compiler will see the header file but never find an implementation for float. So it may compile just fine, but at link time there will be unresolvable symbols.
So they try this:
template struct nothing<float>;
nothing<float> mynothing;
WRONG! Now the compiler can't find the implementation and all you get is MORE errors.
Now you could go back to your A.cpp file and add another instance for float...can you say maintenance, headache, carpal tunnel nightmare? With the commonly used solution you get to have your cake and eat it to. (mostly)
Now you may be thinking why even bother with the extern? Because as your post implies there is a typical use case where most of the time "nothing" will be used with an int template type. Having this occur in potentially hundreds of files can lead to serious compile time and code size ramifications.
Why doesn't the standards committee do something about this mess? They did! They added extern templates! In all fairness it is a difficult issue to resolve after the fact.

OOP C++ - Error as A.h includes B.h which includes A.h again

I'm learning OOP and have a doubt. Suppose I have a file ClassA.h that includes ClassB.h, and at some point my ClassB.h needs to include ClassA.h.
This yelds an error and I think I understand why that happens since I get an infinite include loop. But what to do in this case? Is there a way around this error? Or should I rethink my classes to avoid it? Does this mean my class organization is poorly designed? If so, what would be a way to arrange my "class diagram" and avoid this?
I just want to know what would be the best practice in this scenario. Also, why doesn't the "#pragma once" directive solve this problem? Thanks in advance.
You may also get around this by using forward declaration. Provided you do not create actual object of the class you are including in the header or not inheriting from it, say if you only need pointers of them in the headers you can do this.
Example:
ClassA.h
class ClassB;
//rest of the codes here
ClassB.h
class ClassA;
//rest of the codes here
ClassA.cpp
#include ClassA.h
#include ClassB.h
ClassB.cpp
#include ClassB.h
#inlcude ClassA.h
There is a way to fix it, but it also means your class organization is broken.
The way to fix it is called an 'include guard', though many compilers also support the #pragma once directive. I suppose it isn't working because #pragma once probably doesn't consider a header file included until the entire thing is parsed. And since the recursive inclusion happens in the middle of the header file, it isn't finished being parsed yet.
An include guard is something like this:
In ClassA.h:
#pragma once // Just because. It really should help.
#ifndef INCLUDED_CLASSA_H
#define INCLUDED_CLASSA_H
#include "ClassB.h"
//... rest of header file
#endif
In ClassB.h:
#pragma once // Just because. It really should help.
#ifndef INCLUDED_CLASSB_H
#define INCLUDED_CLASSB_H
#include "ClassA.h"
//... rest of header file
#endif
The organization problem is called a circular dependency, and circular dependencies are generally a bad idea. There are a number of different ways of breaking them, but which to use depends on the exact nature of and original reason for the dependency.
Depending on the problem you can use one of a variety of techniques:
Inheritance from a common base class
Turning one of the two classes into a base class for the other - This is a variant of the previous one.
Forward declarations - This is not so desired because it doesn't really break the circular dependency, it just arranges it so you don't need to also have a problematic circular include dependency.
Turning some part of both classes into a class that they both can use - This is another variant of common base class that uses composition instead of inheritance.
There are other techniques. There is, in fact, a book that has a really wide variety of techniques to use in various situations because removing circular dependencies is a big theme of the book. That book is "Large-Scale C++ Software Design" by John Lakos.
In my past experience , I have solved same problem by using Inheritance.
The way I have solved is .
ClassA -> ClassB : ClassB was inherited by ClassA.
ClassA had common needs that ClassB and ClassA wanted.
then I had resolved "Recursive Include Problem"

Forward declaration / when best to include headers?

I'm pretty clear on when I can/can't use forward declaration but I'm still not sure about one thing.
Let's say I know that I have to include a header sooner or later to de-reference an object of class A.
I'm not clear on whether it's more efficient to do something like..
class A;
class B
{
A* a;
void DoSomethingWithA();
};
and then in the cpp have something like..
#include "A.hpp"
void B::DoSomethingWithA()
{
a->FunctionOfA();
}
Or might I as well just include A's header in B's header file in the first place?
If the former is more efficient then I'd appreciate it if someone clearly explained why as I suspect it has something to do with the compilation process which I could always do with learning more about.
Use forward declarations (as in your example) whenever possible. This reduces compile times, but more importantly minimizes header and library dependencies for code that doesn't need to know and doesn't care for implementation details. In general, no code other than the actual implementation should care about implementation details.
Here is Google's rationale on this: Header File Dependencies
When you use forward declaration, you explicitly say with it "class B doesn't need to know anything about internal implementation of class A, it only needs to know that class named A exists". If you can avoid including that header, then avoid it. - it's good practice to use forward declaration instead because you eliminate redundant dependencies by using it.
Also note, that when you change the header file, it causes all files that include it to be recompiled.
These questions will also help you:
What are the drawbacks of forward declaration?
What is the purpose of forward declaration?
Don't try to make your compilation efficient. There be dragons. Just include A.hpp in B.hpp.
The standard practice for C and C++ header files is to wrap all of the header file in an #ifndef to make sure it is compiled only once:
#ifndef _A_HPP_
#define _A_HPP_
// all your definitions
#endif
That way, if you #include "A.hpp" in B.hpp, you can have a program that includes both, and it won't break because it won't try to define anything twice.

What kind of bad things would happen if you write the whole class in a single file in C++?

In C# or Java, classes are declared and defined at the same time. In C++, the norm is to do that separately. What if we write the whole class in one , say .cpp, file and include that in files that references to it, what kinds of bad thing technically would happen besides a lengthened compilation process?
If your implementation of MyClass is all in the header file MyClass.h then any file you needed to implement MyClass will be included whenever someone includes MyClass.h.
If you change any part of MyClass.h, even if it's trivial (such as adding a comment or even a space) then all files that include it will have to recompile, even if the interface hasn't changed.
Neither of these matters for toy projects, but as you noted, when you have a program that consists of hundreds (or thousands, etc.) of class files, the added compilation time alone makes it worthwhile to separate out implementation from interface.
For instance, if I have the following:
// MyClass.h
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include "Inventory.h"
class MyClass
{
public:
MyClass();
void processInventory(Inventory& inventory)
{
// Do something with each item in the inventory here
// that uses iostream, iomanip, sstream, and string
}
private:
// ...
};
It would more ideomatically be written as:
// MyClass.h
class Inventory;
class MyClass
{
public:
MyClass();
void processInventory(Inventory& inventory);
private:
// ...
};
// MyClass.cc
#include "MyClass.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include "Inventory.h"
MyClass()::MyClass()
{
}
void MyClass()::processInventory(Inventory& inventory)
{
// Do something with each item in the inventory here
// that uses iostream, iomanip, sstream, and string
}
Notice: Including MyClass.h doesn't mean iostream, iomanip, sstream, string, or Inventory.h have to be parsed. Changing how processInventory works doesn't mean all files using MyClass.h have to be recompiled.
Notice how much easier it can be to figure out how to use MyClass now. Header files serve an important purpose: they show people how to use your class. With the modified MyClass.h it's easy to see the list of functions. If each function is defined in the header, then you can't look at just the list of functions. That makes it harder to figure out how to use the class.
You may break the one definition rule.
If you write this:
class foo
{
public:
void doit();
};
foo::doit() {}
and include that in multiple classes, you will have multiple definitions of foo::doit and your link will fail.
But if you make all your classes inline, either by defining them within the class declaration:
class foo
{
public:
void doit() {
}
};
or by explicitly making them inline:
class foo
{
public:
void doit();
};
inline void foo::doit() {}
then you can include that file as many times as you like.
The linker will see multiple definitions of the class's members when you try to combine multiple such objects. Thus, you won't be able to produce a binary from source files that include anything in more than one place.
Typically you separate the declaration and definition of a class. This allows you to use your class in different source files by simply including the declaration.
If you include a .cpp which has both declaration and definition into 2 different source files then that class will be doubly defined.
Each .cpp that the class is included into will compile fine into object files. However each class must have only 1 definition total or else you will not be able to link your object files together.
The most important thing to understand about #include contrasted with other languages importing methods, is that #include COPIES the contents of that file where the #include directive is placed. So declaring and defining a class in the same file will create three things:
Significantly increase your compile
times.
If your definitions are not inline
you will get linker errors, since
the compiler finds multiple
definitions to the same functions
That would expose the implementation
to the user, instead of only the interface.
That is why it is common practice to define large classes in separate files, and on some ocassions, really small classes with small implementations (like smart pointers) in one file(To also implicitly inline methods).
#Bill
I think it is important to underscore Bill's point:
Notice how much easier it can be to
figure out how to use MyClass now.
Header files serve an important
purpose: they show people how to use
your class.
the .h file being more or less the "public" doc to allow the understanding of how your class works in some ways conceptually--an Interface. Remember the source file should be thought of as proprietary. I remember learning a lot about how Unix worked in my early C/C++ days by reading header files. Also remember that inline function complexities should be no more than accessor's
A big reason for a class to be defined in a cpp-file is that it isn't needed publically, it is just a helper function (like e.g. a functor). Some people seem to be afraid to put the complete class in the cpp-file, while that just shows your intent of only using the class there.
Files are usually the atoms of your version control system - if you partition things sensibly into different files, then it becomes possible for a team of developers to check out only the parts they each need to work on. Put everything in one file and you can't do that.

What are some rules with included headers?

I keep running into problems the larger my program gets. For instance, I get the following error:
In file included from WidgetText.h:8,
from LCDText.h:17,
from WidgetText.cpp:13:
Generic.h:21: error: expected class-name before ',' token
Here are those lines:
#include "Generic.h" // WidgetText.h:8
#include "WidgetText.h" // LCDText.h:17
#include "LCDText.h" // WidgetText.cpp:13
class Generic: public virtual LCDText, public CFG, public virtual Evaluator { // Generic.h:21
Here are the contents of the various header files:
//Generic.h
#include "CFG.h"
#include "Evaluator.h"
#include "LCDText.h"
#include "Widget.h"
//WidgetText.h
#include "Generic.h"
#include "Property.h"
#include "Widget.h"
//LCDText.h
class Generic;
#include "LCDBase.h"
#include "WidgetText.h"
This isn't providing much; I know. I'm not sure what else to include. Each header defines a class named after its header, so LCDText.h has a class named LCDText.
The one line declaring class 'Generic' in LCDText.h had to be placed there due to an earlier problem similar to this one. I'm assuming this current issue has a similar solution, but I've failed to find it thus far.
You have a circular dependency: Generic.h includes LCDText.h which includes WidgetText.h which includes Generic.h; the error stems from this basic problem. If you can rework your headers to eliminate this cycle, chances are the error will either resolve itself in the refactoring or the problem will become much more obvious than it is now.
From the code presented here, it seem that you are include the header filed multiple times. To prevent problems you need conditional guards in your header files.
Part of the solution is to add some forward declarations to get rid of these compiler errors (just like you did with your class Generic line). Google will turn up lots of suggestions on how exactly to do this.
Using forward declarations will let you eliminate the cyclic / circular #includes described in this answer.
A forward declaration lets you include references to and pointers to the forward-declared class, and it lets you pass the forward-declared class as a parameter, but it does not let you derive from or include an instance member of the forward-declared class. So your Generic class needs a way to #include (and not just forward-declare) the header files for LCDText, CFG, and Evaluator. If it can't do that because LCDText, CFG, or Evaluator need to #include (and not just forward-declare) Generic, then you need to rearrange your hierarchy to fix this (for example, by making a member variable a pointer or reference to a class instead of making it an instance of a class).
However, using multiple inheritance like this (and especially using the diamond inheritance implied by two virtual inheritances) is a definite code smell. It suggests that you should be designing your class hierarchy differently. For example, maybe you need to be favoring composition over inheritance. That would make cleaning up your forward declarations and cyclic dependencies a lot easier.
Edit: You mentioned that you've been running into this problem more as your code base gets larger. I'm told that John Lakos's Large-Scale C++ Software Design is a good reference for managing issues such as header file dependencies in large projects, although it may be overkill for where your project is right now.
Others have already pointed out the circular dependency but if you're still unsure of how to fix it then it looks for all the world as if you need to forward declare Generic in WidgetText.h i.e. line 8 becomes
class Generic;
If you've already tried that, and it sounds as if you have, then you need to examine how you are using Generic in WidgetText.h and see if you can eliminate places where you are relying on having the full definition eg. change an aggregated Generic to a Generic* or move an inline member that accesses a Generic method into an out-of-line definition in a source file.