Reputation: 692
I have two questions
lets say there is a base class and several derived classes, the derived classes are going to have all of the #include
statements (like #include <iostream>
etc) and using
lines of the base class.
1. is it considered a good practice to write the base class's #include
statements and using
lines in the in the derived classes h. file anyway?
2.same question regarding composition - class A has an object of class B as a member, is it a good practice to writes Bs
#include` statements in A's h. file anyway?
thanks!
Upvotes: 0
Views: 3908
Reputation: 27528
lets say there is a base class and several derived classes, the derived classes are going to have all of the #include statements (like
#include <iostream>
etc) and using lines of the base class.
Not at all.
First of all, you are not supposed to put using
lines at top-level scope in header files. This is a common beginners' mistake.
Second, what makes you think the derived class needs all #include
s of the base class? The derived-class header file needs to include the base-class header file, and the derived-class implementation file needs to include the derived-class header file.
This already gives you all includes.
base.h:
#include <string>
class Base
{
// ...
virtual std::string f(); // no `using`
};
derived.h:
#include "base.h"
// no need for <string> here
class Derived : public Base
{
// ...
virtual std::string f();
};
derived.cpp:
#include "derived.h"
// no need for <string> here
std::string Derived::f() // could have used `using std::string`
{
// ...
}
Now of course, it's technically possible to actually do it otherwise, in a more complicated fashion, like this:
base.h:
// no <string>?!
class Base
{
// ...
virtual std::string f();
};
derived.h:
#include "base.h" // still no <string>?!
class Derived : public Base
{
// ...
virtual std::string f();
};
derived.cpp:
#include <string> // ah, OK
#include "derived.h"
std::string Derived::f()
{
// ...
}
This works only because the compiler doesn't separately compile header files but only compilation units (~= .cpp files) as a whole, after all includes have been processed.
But talk about horrible programming style. Why would you want to force everyone who derives from your class to include extra headers?
2.same question regarding composition - class A has an object of class B as a member, is it a good practice to writes Bs#include` statements in A's h. file anyway?
It depends. If A
's header needs access to any of B
's members, then you have to use an include, and in that case, again, you just include what you need in b.h and let a.h #include "b.h"
.
If A
's header only needs a pointer or a reference to B
, or just a return value, then you can use a forward declaration in order to potentially speed up compilation. Of course, speeding up compilation is not something a C++ beginner should care about, because a lot of time will pass until you will be developing software which take hours to build :)
Anyway, for completeness' sake:
a.h:
class B; // forward declaration, no #include
class A
{
// ...
B f();
B *ptr;
B &ref;
};
a.cpp:
#include "a.h"
#include "b.h" // need the include here
B A::f()
{
B obj;
return obj;
}
b.h:
class B
{
// ...
};
Upvotes: 1
Reputation: 5407
In answer to question 2: typically you would include class B's header file in A's header file (so all the includes needed for A will automatically be included).
However, as pointed out in Logicrat's answer, you could alternatively include only a pointer to B in A. In this case you can use a forward declaration of B in A.h instead of including B.h. The downside to this is that all functions that need to make use of B must then go in A.cc (which will definitely have to include B.h). The advantage is that you can greatly reduce the quantity of code in the header files (since each #include copies an entire header file into the current file just before compilation), which can speed up compilation times.
Upvotes: 1
Reputation: 4468
I think it is a good practice to have each include
file actually #include
any of the definitions it needs, so that in your main program, you can #include
your most deeply derived class without having to have additional #include
statements for the definitions that class needs.
You can have class definitions contain pointers to previously undefined classes, as follows:
class forward_ref;
class myClass :
Public:
myClass(){}
forward_ref* ptr_to_forward_ref;
};
Upvotes: 3