Thread: another #include question

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    242

    another #include question

    If you put an #include where appropriate in a header file, should you duplicate it in the file where you have the function definitions as well as in the file with main()?

    Here's an example:

    I'm using strings and hence put in the file account.h the statement #include <string>

    Now in the file account.cpp, the following will compile:

    Code:
    #include <iostream>
    #include "account.h"
    using namespace std;
    
    void Account::showAcct() const
    {
    	cout << "Name: " << name << endl;
    	cout << "Account number: " << acctNum << endl;
    	cout << "Balance: $ " << balance << endl;
    }
    void Account::deposit(const double depAmt)
    {
    	balance += depAmt;
    }
    void Account::withdraw(const double wdAmt)
    {
    	balance -= wdAmt;
    }
    
    std::string Account::test()
    {
    	return "tested";
    }
    The last function I even threw in extra just to see if it would work without the #include.

    I also don't have a #include <string> in the file with main(), but it also doesn't make explicit use of strings and does have #include "account.h" of course.

    Is it good programming practice to put the #include in explicitly in all these spots even though, using this case as example, <string> gets included because it's included in the account.h file?

    Or, asking my question a bit differently, should you explicitly #include the various libraries you need even if you've indirectly #included them already through reference in a header file?

  2. #2
    Webhead Spidey's Avatar
    Join Date
    Jul 2009
    Posts
    285
    Well, only the person who created the header fie knows what all its including. So its more clear to include them as you need.
    Spidey out!

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If you use a string in the file, then #include <string>.

    In this case, you are using strings in account.h and account.cpp, so #include <string> in both. You are not using strings in main, so don't #include <string> there.

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Daved View Post
    If you use a string in the file, then #include <string>.

    In this case, you are using strings in account.h and account.cpp, so #include <string> in both. You are not using strings in main, so don't #include <string> there.
    If I #include a file in a header, I usually don't #include it in the .cpp file of that header; what's the point? I'd be #including it twice then. Plus, if I remove it later, I'd have to remember to remove it from both files.

    On the other hand, if you #include a header file in the main .cpp or an unrelated .cpp, then it would probably be better not to rely on certain header files always being included, otherwise you end up with tight coupling...

    A header and the .cpp that directly belongs to it are basically one unit as far as I'm concerned; so I don't duplicate #includes between them.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by cpjust View Post
    A header and the .cpp that directly belongs to it are basically one unit as far as I'm concerned; so I don't duplicate #includes between them.
    I tend to agree with that.

    However (and I realise cpjust is not suggesting otherwise) that does not mean that headers should #include everything.

    Essentially I write headers to #include everything that is necessary for code to use the functionality of a "unit", and .cpp files to #include everything (usually including the header) needed to implement the functionality of a "unit".
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> if I remove it later, I'd have to remember to remove it from both files.
    Actually, that's a bad idea. The rule is to #include it where you use it. If you remove it from the header, how do you know you don't use it in the cpp file separately from how it was used in the header?

    >> that does not mean that headers should #include everything.
    Of course not. Each file should include what it uses. That way you don't have to worry.

  7. #7
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Daved View Post
    >> if I remove it later, I'd have to remember to remove it from both files.
    Actually, that's a bad idea. The rule is to #include it where you use it. If you remove it from the header, how do you know you don't use it in the cpp file separately from how it was used in the header?
    Obviously you'd need to selectively remove it from either the header or both, but it's still one more thing to needlessly worry about. I treat it kind of like the rule of declaring variables closest to their first use... If I need a type in the header file, I #include it there, otherwise if I only need it in the .cpp file, I include it there.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> If I need a type in the header file, I #include it there, otherwise if I only need it in the .cpp file, I include it there.
    That's fine, but I don't think that's what we're talking about.

    The question is whether one should include the header in the source file if it is used in both the source and the header and is already included in the header. IMO, the answer is yes, absolutely. The reason is that if you no longer need it in the header, and therefore remove it, you could inadvertently break the source file.

    Obviously this isn't a big deal, but to answer the OP's question, I would rather have a simple and steadfast rule with one extra step than take the chance of inadvertantly breaking my code.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by cpjust
    Obviously you'd need to selectively remove it from either the header or both, but it's still one more thing to needlessly worry about.
    I think that you may have to worry about getting the includes right either way. Consider a case where you require <istream> in a header. After maintenance, <iosfwd> is required, but <istream> is included via another header, say another standard header. You distribute the source, and some users complain that the program cannot compile. It turns out that on a different implementation, <istream> is not included via that other standard header, and you forgot to #include <istream> in the source file.

    Quote Originally Posted by cpjust
    I treat it kind of like the rule of declaring variables closest to their first use... If I need a type in the header file, I #include it there, otherwise if I only need it in the .cpp file, I include it there.
    In a way, I agree: if I can get away with a forward declaration of a class instead of its entire definition, I try to do so.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    May 2009
    Posts
    242
    cpjust's solution seems pretty solid to me. Thanks very much to all for the very helpful discussion!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Buidl Library with ./configure script
    By Jardon in forum C Programming
    Replies: 6
    Last Post: 07-24-2009, 09:36 AM
  2. Precompiled header question
    By donglee in forum C++ Programming
    Replies: 13
    Last Post: 01-22-2009, 01:23 AM
  3. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  4. Socket Question
    By DaveHope in forum Networking/Device Communication
    Replies: 12
    Last Post: 06-21-2005, 04:50 PM
  5. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM