tags:

views:

229

answers:

6

By common I don't mean utility, I mean a header that holds enums that multiple types want to use, etc.

For example, if multiple types can have a Color, which is an enum, you'd want to make that available. Some people would say to put it into the class that it "fits best with", but this can create header dependency issues.

I really dislike creating a header that contains things like this, because it seems like it makes the code more complex. I'm looking for other's thoughts on what techniques they employ when they run into a situation like this. If they use a "Common" header, etc.

+2  A: 

Common header is ok as lomg as there are few people working on your project. once you have 20+ people editing that file and merging it back and forth - you get a nightmare.

Alternative would be to have a color.h or have common/color.h which will enforce some structure on your files.

Zepplock
I've considered that, but having a header file with one enum seems...wrong.
Anonymous
Why? It keeps your data separate and easy to view and modify.
GMan
(+1) For the sound advice, if your going to have multiple people interfering with the single common file (--i.e., if it is a hot file) try to split it up into relatively colder chunks... you can always concatenate them as a build step. Such separation into colder files will also help in your version control.
Hassan Syed
"once you have 20+ people editing that file and merging it back and forth - you get a nightmare". Switch to git ;-)
Steve Jessop
I'm now convinced that separating the enums, etc. into different header files is the way to go.
Anonymous
Moving public class enumerations to their own header can speed up compilation too - if you need to use the enum from another class you just #include the header containing the enumeration.
Rob
+4  A: 

I always use a Common.h file that almost never changes and contains definitions that are extremely likely to be needed in virtually all files. I think it increases productivity so that you don't have to open another .cpp file and copy the list of all the headers you know you'll definitely need.

For example, here are two excerpts from my Common.h:

typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned char uint08;
typedef signed char int08;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned int uint32;
typedef signed int int32;
typedef unsigned long long uint64;
typedef signed long long int64;
typedef const char cchar;
typedef const bool cbool;
typedef char Byte;


#ifdef ASSERT
/* Re-defining assert */
#undef ASSERT
#endif

#ifdef DEBUG
#ifndef ASSERTIONS
#define ASSERTIONS
#endif
#endif

#define ASSERT_ALWAYS(Expression)   if (!(Expression)) FatalError(ErrorInfo("Assertion Failure", #Expression, FUNCTION_NAME, __FILE__, __LINE__))

#ifdef ASSERTIONS
#ifdef DEBUG
#define ASSERT(Expression)   ASSERT_ALWAYS(Expression)
#else
#define ASSERT(Expression)   if (!(Expression)) ErrorLog("[Release Assertions]: The following assertion failed: " # Expression)
#endif
#else
#define ASSERT(Expression)
#endif
Andreas Bonini
I've started using <boost/cstdint.hpp> and their ISO/IEC 9899 standard types (sometimes called C99 types), e.g. uint32_t.
ceretullis
Yes, <boost/cstdint.hpp> or <stdint.h> (depending on your platform, third-party code policy) are much better than trying to use your own typedefs.
Tom
+2  A: 

IMO Common headers are good practice if you restrict them to containing things that seldom change like

typedef unsigned int UINT32;

If you find yourself editing this file a lot, then you have stuff in it that doesn't belong there.

John Knoeller
+1  A: 

Personally I am not a fan.

  1. 1. I means that when you modify a constant (or type) that is used in only one place, you need to recompile your entire project.
  2. 2. The value of the constant (or definition of the type) and the use of the said constant (or type) are in two different places.

Generally speaking, I like to define a constant that is used only once, next to where it is used. This means that if I want to know what value the constant holds, it is right there for me to look at. It also means that I only need recompile on file when the said constant changes.

There is a case for a constant header file if the constant or type is used extensively or if a constant or type is shared across modules.

doron
+1  A: 

If you want 'global' enums then put them in their own namespace instead of polluting the global namespace, e.g.:

// Types.h

namespace MyTypes
{
    enum Color
    {
        RED,
        BLUE,
        GREEN,
    };
}

Personally I prefer to keep enums associated with a class but YMMV.

Rob
A: 

I prefer to be explicit about what each and every cpp file needs. I find it's easier in the long run and that it prevents 'common' headers from causing files to be rebuilt when they don't need to be. As a project grows, having a strict 'include only what you need' policy can help keep build times down. The price of this is a little thought when you're initially building a new class. I often have header files just for a single enum or typedef and I even go as far as having a special build configuration which builds without precompiled headers and (since I work with Visual Studio) use #pragma hdrstop to define my precompiled headers rather than having every file need to include a common file for this purpose.

Over the years I've found this to work very well at keeping build times down and allowing code to be moved around (out into libraries or across into other projects) or built for test harnesses.

I view common headers as unnecessary coupling which should be removed and, to be honest, a sign of laziness and lack of attention to detail.

Len Holgate