Medvednic
Medvednic

Reputation: 692

same #include statements in derived classes

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

Answers (3)

Christian Hackl
Christian Hackl

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 #includes 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

dshepherd
dshepherd

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

Logicrat
Logicrat

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

Related Questions