Thread: Question in including tempolate header files.

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    14

    Question in including tempolate header files.

    Assume that two pieces of code use the same tempolate header. If the two pieces are compiled separately and linked together. Then there might be a duplicated definition error. How to avoid this problem?

    To be clearer, e.g. I have these three files:
    a.hh:
    Code:
    int func(int i){ ... }
    b.cc:
    Code:
    #include "a.hh"
    ...
    .
    c.cc:
    Code:
    #include "a.hh"
    ...
    Compile and link:
    Code:
    g++ -c b.cc
    g++ -c c.cc
    
    g++ b.o c.o

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What template?

    You appear to have an actual function in your .hh file (based on what you've posted). The header file should contain the prototype only, none of this
    Code:
    {...}
    bit. That bit, the actual function, belongs in a .cc file instead.

  3. #3
    Registered User
    Join Date
    Dec 2008
    Posts
    14
    That's just for example. The real case is that the function is a template.

    a.hh:

    Code:
    template <typename T> T func(T i){ ... }


    Quote Originally Posted by tabstop View Post
    What template?

    You appear to have an actual function in your .hh file (based on what you've posted). The header file should contain the prototype only, none of this
    Code:
    {...}
    bit. That bit, the actual function, belongs in a .cc file instead.

  4. #4
    Registered User
    Join Date
    Dec 2008
    Posts
    14
    my bad. Just realized the code in question is not a template header.

    Quote Originally Posted by plutino View Post
    That's just for example. The real case is that the function is a template.

    a.hh:

    Code:
    template <typename T> T func(T i){ ... }

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by plutino View Post
    ... Then there might be a duplicated definition error. How to avoid this problem?
    Use Header Guards:
    Code:
    #ifndef SOME_UNIQUE_NAME
    #define SOME_UNIQUE_NAME
    
    // Put your header stuff here.
    
    #endif  // SOME_UNIQUE_NAME
    "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

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Every header should have the guard that cpjust posted. Alternatively you can use #pragma once inside of MSVC 2003+ which is not portable but very convenient.

    You should also refrain from placing all your classes in the global namespace. Prefer something like:

    Code:
    #ifndef SOME_UNIQUE_NAME
    #define SOME_UNIQUE_NAME
    
    namespace some_namespace
    {
       struct SomeStruct
       {
       };
    
       class SomeClass
       {
       };
    }
    
    #endif
    As well you should include only what is absolutely necessary in header files. I prefer to include in the cpp file if I can get away with it. Sometimes though your class function prototypes may require you to include a header from another object, or another object in another project.

    There is a way to include in such a way that you do not have to include in the header itself. For instance if you needed to include <windows.h> but didn't want to bring in the entire header into your header you could do this:

    SomeClass.h
    Code:
    #ifndef SOME_UNIQUE_NAME
    #define SOME_UNIQUE_NAME
    
    namespace some_namespace
    {
       struct SomeStruct
       {
       };
    
       class SomeClass
       {
           ...
           private:
              CRITICAL_SECTION m_CriticalSection;
       };
    }
    
    #endif
    SomeClass.cpp
    Code:
    #include <windows.h>
    #include "SomeClass.h"
    ...
    This is prone to abuse and confusion but it is a valid practice in certain circumstances. As long as windows.h is included prior to SomeClass.h, SomeClass.h will not complain about undefined Win32 symbols.

    Just keep in mind that if you include unecessary stuff in your headers everyone who includes your header will get all of the unecessary stuff.
    Try to stay away from cyclic dependencies where object A needs object B but A also needs B. Sometimes this is unavoidable in which case you must use forward declares.

    I think I covered most of what can cause some major header headaches.

    Templates bring in a new headache since the code must be in the header. I normally bring in the code as a separate cpp and this is the only time I actually include the cpp in a header. The other alternative is to write the template code in the header.
    Last edited by VirtualAce; 12-17-2008 at 12:35 AM.

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    There is a way to include in such a way that you do not have to include in the header itself. For instance if you needed to include <windows.h> but didn't want to bring in the entire header into your header you could do this:
    But then, wouldn't every file that includes "someclass.h" have to include <windows.h> first - even if that file doesn't need that header - creating nothing but confusion as the dependency is still there?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by anon View Post
    But then, wouldn't every file that includes "someclass.h" have to include <windows.h> first - even if that file doesn't need that header - creating nothing but confusion as the dependency is still there?
    Agreed. I would say that's a very bad thing to do because it requires everyone else to know that they need to include certain header files before including yours instead of just including it in one place.

    Chapter 23. Make header files self-sufficient
    "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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Including my own header files
    By bushymark in forum C Programming
    Replies: 17
    Last Post: 11-03-2009, 09:09 PM
  2. Including kernel header files
    By carmaa in forum C Programming
    Replies: 0
    Last Post: 02-03-2008, 03:43 PM
  3. Many Header Files
    By matth in forum C++ Programming
    Replies: 3
    Last Post: 03-08-2005, 02:45 PM
  4. quick question about header files
    By Kirstin in forum C++ Programming
    Replies: 3
    Last Post: 10-21-2001, 11:21 AM
  5. question about header files
    By ArseMan in forum C++ Programming
    Replies: 2
    Last Post: 09-21-2001, 02:33 AM