Is it necessary to seperate the headers from the source?

For example I don't know why but I love to do:

//Foo.H

class Foo
{
    Foo(){}
    ~Foo(){}

    void Func()
    {
       //.........
       //.........
    }

    void Func2()
    {
        //........
        //........
    }

};

Instead of doing:

//Foo.H
class Foo
{
   Foo();
   ~Foo();

   void Func();
   void Func2();
};

//Foo.cpp
Foo::Foo()
{
  //.....
}

Foo::~Foo()
{
   //......
}

Foo::void Func()
{
   //.....
}

Foo::void Func2()
{
    //....
}

The second example which Hate to do seems like so much more work. Not only that but I'd have to constantly switch back and forth between headers and sources to see whats declared where or what contains what. But now I'm looking up all my habbits to see if they cause performance degradation and I've read the first one does whereas the second doesn't :S

I'm also reading that if i put my definitions inside the class, it's automatically inlined and that if I put the inline keyword in there then it's even worse :S Should I just leave them in there as inline and if not then why? Is there a way to define them inside the class and NOT be inlined?

Is this true? Am I actually doing something bad? I'm being told to never put the definitions in a header.. Only declarations.. Apparently it slows down compile time and slows down my program which is what I read at stack overflow from someone asking a similar question. I use header guards by the way.

I just really don't like having that many unneccesary files when I can just include my header with everything in there already..
So is it bad? Also why should a coder use the scope operator like that instead of putting it all inside the class? Is there an advantage such as performance/compile time or is it just style? C# doesn't seem to care whether or not everything is in one file..

Recommended Answers

All 8 Replies

It's not necessarily a bad thing or a good thing; it depends on the situation. The thing that you have to remember is that if you change the header at all, then all the files that depend on that header are going to need to be re-built, which can lead to long build times once your project gets moderately complex. I generally only use this method for VERY simple methods that I don't think will change very often at all (single-line getters and setters are an example).

There's a point about readability too. If you didn't write a class, you're just using it, then you don't necessarily care about how the methods actually work - you just want to see quickly what features a class has. In this case, looking at the header is more difficult, you can't get that many method names on the screen in one go, you can't pick out what typedefs/enums are in the class etc. In the codebases that I work on it is certainly the case that any one person didn't write most of it, so the inspectability of the header is quite important.

Of course, if you're making a template class, then the definitions need to go in the header. However, you should still put them outside the class declaration, for readability reasons just mentioned.

I don't think that the number of files in a project is an important metric, so I wouldn't worry too much about that :)

commented: Thanks :D +5

Not only that but I'd have to constantly switch back and forth between headers and sources to see whats declared where or what contains what.

If it annoys you to switch back and forth between the header and source when you are implementing the functions, then here's a trick for you. Simply write the code in the header file (within class declaration), so you won't have to switch all the time, and then, once you have finished implementing and testing them, copy all the longer functions (longer than a few lines) into the source file, clearing them from the header file.

But now I'm looking up all my habbits to see if they cause performance degradation and I've read the first one does whereas the second doesn't :S

That depends on your definition of performance. The first one (definitions inside the class declaration) will lead to faster code at run-time, but possibly a larger executable at the end too. The second one will lead to faster compilations and fewer compilation dependencies (fewer needs for complete recompilations).

I'm also reading that if i put my definitions inside the class, it's automatically inlined

Putting the definitions inside the class will make the compiler attempt to inline the function by default. Inlining is never guaranteed, it is always up to the compiler to make that decision, whether it is worth inlining or not. And btw, inlining is a good thing, it is one of the most important performance optimizations that a compiler can do.

and that if I put the inline keyword in there then it's even worse :S

Putting the inline keyword on function that are defined inside the class declaration is completely useless, it has no effect whatsoever.

Should I just leave them in there as inline and if not then why?

If the functions are small (one to a few lines of code, like simple getters-setters), then it is probably better, for performance reasons, to leave them implemented within the class declaration. Small functions are likely to be inlined by the compiler, and they are also likely to be called often, meaning that the performance boost from the optimization could be significant at the end. Also, because the functions are small, they don't break the readability of the class declaration.

Is there a way to define them inside the class and NOT be inlined?

No. Why would you want to do that anyways? You can define functions outside the class declaration and mark them as inline and put the definition in the header file (but outside the class declaration) if you don't want to clutter the class declaration and still want the performance gain that inlining can give you. There is no reason for wanting to put the definition in the class while denying yourself this optimization, and the language doesn't have a mechanism for that, exactly because nobody would want to do that.

Is this true? Am I actually doing something bad? I'm being told to never put the definitions in a header.. Only declarations..

Putting the definitions inside the class has three bad effects:

  • It reduces the readability of the class declaration, i.e., you no longer clearly see the list of functions, data members and nested types (or enums) because there is all this code in the way. And this problem is not to be discarded as simply a matter of taste or style, when you work on larger projects, and possibly within a team of developers, class declarations are a way to communicate, clearly, the usage of your class. Remember also, that even if you work alone on a project, you can often find yourself looking back at code you wrote months or years earlier and if the class declaration and usage isn't clear, you'll be in as much trouble understanding it as any other programmer who isn't the author of that code.
  • It increases the compilation time of all the code that uses that header. The #include statement is pretty much just a copy-paste command, it tells the compiler "fetch this file and paste all its content at this line". So, the compiler fetches all the headers and creates one big file containing all the code to be compiled, and then compiles it. If all your headers contain all their code, every source file that uses your header ends up recompiling your entire code-base as opposed to just compiling its own code. This can be significant on larger projects (measured in minutes or even hours of compilation).
  • It increases the dependencies to the implementation in the header file. If you decide to change something in the implementation of a function in a header, then it will require that all the code that uses that header file be recompiled, and when it takes between ten minutes to a few hours to compile the code, that can be really annoying.

But, the above doesn't mean that it is bad all the time. A good example is those simple set-get functions in a class which often end up being a single line of code. Because they are short, they don't break readability, they don't cause significant increase in compilation times, and they are good candidates for inlining, thus, improving performance. Also, being pretty trivial functions, it is unlikely that they will change significantly in the future.

And then, of course, there are special cases in which you can't avoid putting the definitions in the header file, notably, when writing templates (class or functions). And then, also, there are cases where you just don't have the option to put the definitions in the header file, notably, when implementing a compilation firewall for an external dependency (and a few other more technically advanced cases, like avoiding inlining of virtual functions in concurrent or cross-module programs).

I just really don't like having that many unneccesary files when I can just include my header with everything in there already..

It is true that having all the code in the header files is more convenient, at least, it appears to be. But when the project gets larger, you will be happy that you put all the significant implementations in source files.

Also why should a coder use the scope operator like that instead of putting it all inside the class?

Huu???

C# doesn't seem to care whether or not everything is in one file..

Java/C# have a completely different compilation model (somewhere between a native language like C/C++ and an interpreted language like Python), so you can't compare, the rules are different. For example, one object-oriented native language that exists is Delphi (or Object-Pascal) which forces you to separate the implementation from the declaration (it calls it the interface) into separate sections of the same file, but it also has syntax features to automate the creation of simple set-get functions so you don't have to implement those if they are trivial. This is actually one of the strengths of Delphi, it has a much smarter compilation model which turns out that it can compile a large code-base lightning fast (some years ago, I had written the same library in both languages, C++ and Delphi, it was about 40 thousand lines in either language, it took about 20min to compile in C++, but took about 0.5 second to compile in Delphi!). Different languages have different compilation models, you just have to understand it and live with it, and the compilation model in C++ is not one of its strengths and is often (and rightly so) criticized (often, this compilation model is casually called the "stupid linker model", because it requires a very smart compiler and a very stupid linker, but formally, it is called the "separate compilation model").

commented: Very Very Amazing Post. I'll Change all My Files Now. +5

Hey I'm having a problem Splitting them.. I split everything and they all compile but there's actually two problems.

One is a template class and the other is the overloading of operator << with ostream.. My other operators also give the same problem if they have two arguments.
Operator problem:

//File.HPP

class Point
{
   Point(){}    //One.. I don't know if I should put the braces here or outside the class.
   ~Point(){}   //Same as above.

   friend ostream& operator << (ostream& Str, const Point &PT);  //Declaration.   
}

//File.CPP

inline ostream& Point::operator << (ostream& Str, const Point &PT)
{
    Str<<"("<<PT.X<<", "<<PT.Y<<")";
    return Str;
}

//Gives the error: error: 'std::ostream& Point::operator<<(std::ostream&, const Point&)' must take exactly one argument|
//Whereas when inside the class I get no error :S

Template Problem:

#ifndef TEMPLATES_H_INCLUDED
#define TEMPLATES_H_INCLUDED
#include <iostream>
#include <vector>

using namespace std;

template <typename T>
class CustomType
{
    private:
        vector<T> TypeData;

    public:
        CustomType(){}
        ~CustomType(){}

         //Other definitions here..
        CustomType& operator >> (const T& t);

        void SetLength(size_t NewLength);
        inline ostream& operator << (ostream& Str, const CustomType &CT);
};

#endif // TEMPLATES_H_INCLUDED

//Then In the .CPP file I put the definitions but it Errors like mad.

When I put all the definitions for the template in the header file inside the class, I get no errors :S Same with the operators. As for the constructor, should I leave the braces in there since its default anyway? And it's so small :S

It isn't something of bad or good than necessity.. I used to think writing all the function definitions of the class is better as it saves me time, space and effort.. Yes that is true only when u are making a small program.. When u start making a program which tends to a complete software often comprising 5000+ lines, u realise its crazy when everything is inside the class itself.. So, like said earlier too, its more of whats right for you and when and not whether it should be done or not !! Preferably, its better to separate it..

@ Mike,
That was quite a mouthfull :P Btw, gr8 qualifications.. B.Eng., M.Sc., M.Sc.(Tech.), PhD candidate in Aerospace Robotics.. I must say, VERY impressive !!

:D I always read all of mike's posts. Him, Narue, Ancient Dragon, Lambdabeta, and Deceptikon. Even if its pages long. Turns out he's right though because it was taking me 5 mins to compile 13k lines of code that was IN the classes..

I separate them and it's a lot more than 13k but it compiles in roughly a 10-20 seconds. So.. I actually think that it NEEDS to be separated. Also when compiling, it only re-compiles the file I changed which is a huge benefit! But I still cannot get my operator overloads working. Especially the ostream and the questions I posted in my last post above.

The first problem:

inline ostream& Point::operator << (ostream& Str, const Point &PT)
{
    Str<<"("<<PT.X<<", "<<PT.Y<<")";
    return Str;
}

Should be replaced by:

ostream& operator << (ostream& Str, const Point &PT)
{
    Str<<"("<<PT.X<<", "<<PT.Y<<")";
    return Str;
}

The point is that when you declare a friend function within a class, what you are doing is declaring a free-function (not a member function), within the namespace that the class is in, which has access to all the private members of the class (this also means that if you don't need the function to be a friend of the class, don't make it one, just make it a normal free-function). In any case, a free-function does need the Point::. Also, because you put the function in the cpp file, it makes no sense to put the inline keyword there (but if you decide to put the function in the header, which you might since it is short, then you can put the inline keyword).

For the second problem with this line:

inline ostream& operator << (ostream& Str, const CustomType &CT);

the problem here is that you are declaring this operator as a member function of CustomType, and you are giving it two arguments. This is impossible and incorrect, and the source of all the troubles. Either you replace the inline keyword here with the friend keyword, and do as above. Or, you move it out of the class declaration (as a normal (or non-friend) free-function).

That should fix your problems.

Hey you solved the first problem but unfortunately the templated class still throws like 50m errors unless everything is inside the class.

I researched it and apparently it's common to define the templated functions in the class itself :S Apparently boost does this.

Anyway my entire templated class HEADER looks like and all my definitions are in the CPP file but that gives errors like mad:

template <typename T>
class CustomType
{
    private:
        vector<T> TypeData;
        void Insert(){}
        template<typename A, typename... Args>
        CustomType& Insert(A FirstArg, const Args... RemainingArgs);

    public:
        CustomType(){}
        ~CustomType(){}

        template<typename A, typename... Args>
        CustomType(A FirstArg, const Args... RemainingArgs);

        int size();

        CustomType& operator [](int I);

        const CustomType& operator [](int I) const;

        operator const vector<T>& () const {return TypeData;}

        bool operator == (const CustomType &CT) const;

        bool operator != (const CustomType &CT) const;

        CustomType& operator = (const CustomType &CT);

        CustomType& operator >> (const T& t);

        void SetLength(size_t NewLength);

        template<typename A, typename... Args>
        CustomType& operator ()(A FirstArg, const Args... RemainingArgs);

        inline ostream& operator << (ostream& Str, const CustomType &CT);
};

Since the above gives errors I just put all the definitions back inside the class of the header instead.

For templates, the definitions of the functions must appear in the header file, if they are too long you can simple put them outside the class declaration, but still in the header file (i.e., after the class declaration). This is one of the few major drawbacks of templates.

Read this FAQ.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.