Separating classes to .h and .cpp

Started by
10 comments, last by Antheus 13 years, 12 months ago
So, I've been programming for around 6 years now. My first language was C++ and it is my favorite still. When I was first learning about classes, I heard that they had to be separated into .h and .cpp files, having the declaration in the header and the implementation in the source. So, I did this for every class I made. Only later did I realize that you can write the source for the functions inside the declaration of the class inside the header file with no source file needed. So, I started doing this for every class. In my experience, separating classes into .h and .cpp files compiles much slower than just declaring the class and implementation in the .h. Also, it causes you to have to write a good amount more code! Just to clarify, when I say declaring and implementing the class in the .h file, I mean like this:
class SomeClass {
  public:
    SomeClass() { some_int = 0; }
    ~SomeClass() {}

    int getSomeValue() {
      int some_value = 0;
      //do something here
      return some_value;
    }

  private:
    int some_int;
};
All in the .h file. So my question is, what is the point of separating a class into two separate files, a .cpp and a .h??? It seems so unnecessary, time consuming, and annoying. I realize that it is an accepted practice, but is there any good reason?
Advertisement
Well, for one, I think it makes the code cleaner. It also helps to see what the class contains (all of the functions) without having to scroll through all of the implementations to try to find each function declaration. This, of course, doesn't really matter if you have a UML diagram for that class.

That's about all I can think of right now.
"All you have to decide is what to do with the time that is given to you." - Gandalf
I suppose this is true, but if this is the only reason, I think I'd rather just keep the declaration and implementation in the same file ><.
Quote:Original post by Shadeirou
In my experience, separating classes into .h and .cpp files compiles much slower than just declaring the class and implementation in the .h.


It should be the contrary: with separation, if you modify the implementation of one method (your //do something here) you don't have to recompile every single other file that includes the header.
By providing the implementation in a separate file you can also hide dependencies to the user. As an example, when prviding a library that depends on other ones, putting all the code in the .h will force you to provide also the .h of the libs you are using. However, by statically linking to them and by having the implementation in the .cpp file you can completely hide that extra code that in fact the end user doesn't need.
Quote:Original post by Shadeirou
In my experience, separating classes into .h and .cpp files compiles much slower than just declaring the class and implementation in the .h.


This is only true if you look at the compile time of each file in isolation. However, imagine you are on a bugfixing journey through the innards of a very large project. With your approach, whenever make some change to some class, you will have to recompile *all* classes that depend on the changed class, no matter how small the change was. For a basic class, this means recompiling major parts of your project.

If you separated declaration and definition into .h/.cpp files, you will only have to recompile one file, namely the cpp you changed. For a task like bugfixing where you are required to make lots of small changes and test them immediately, this is very helpful.
This however only applies to implementation changes. If you change the interface (i.e. the .h file) you will still have to recompile everything. But then on the other hand, interfaces don't change nearly as often as implementations, especially in matured projects.
I actually just found a reason that satisfies me enough to always separate classes into the two files... Let's say I have class A and class B. Assume that class A uses variables of class B and class B uses variables of class A. Well, if the classes are declared in only the header, class A would include class B which would then attempt to include class A only to be stopped by the header guard and an error would be produced of type "no type A declared," or something similar. When I tried this with the classes separated into .h and .cpp files, and had a forward declaration of class B in the class A header and vice versa, it worked just fine.

Anyway, thanks for the quick replies ;).
#1: Even if you implement a function in the header, for God’s sake at least implement it outside of the class definition.

// == Definition.class CClass {    CClass();};// == Implementations.CClass::CClass() {}



#2: Functions in the header files are automatically inlined whenever possible. This creates a lot of code bloat and may cause linkage issues as well when your library links against one memory manager and your EXE against another (or CRT library or whatever) (common on Windows) and they are both calling the same class function from a header file that has been copied to both modules and linked against different allocators in each library. Just one example.

It also degrades compiler performance substantially, as any change to the implementation results in the recompilation of all translation units that know about the header.

Putting the implementation in the .CPP (translation unit) files also allows you software security.
Let’s say you wanted to make your own game engine. And a client asks you to make him a game. You decide to use your engine, of course. But the client says he wants the full source to the game. You cannot give him the source of your engine because that is your own big money maker and is confidential.
Well, if you had been putting your code in the .CPP files where they belong this would be no problem. Build your engine as a library, link his game against it, and when you give him the code you just give him your engine as a binary library, his game code, and the headers for your library.
You have to provide the headers in order to link against the library.
If you have been putting your code in the headers, kiss your luck goodbye; anyone can steal your whole engine rather easily.



The code belongs in the .CPP file unless there is a reason to put it in the header. Simply laziness is not an excuse. I am the CTO of my company and I enforce a lot more coding practices than just this. Frankly, I could not hire someone who views such a simple practice as “annoying”. Too few people these days care about organization.

If coding speed is your concern, write macros to paste a lot of repeated comments and code for you. Ctrl-3 gives me a Javadoc function header. Ctrl-1 makes a whole new class for me, with include guards, copyright header, and class name and constructor for me. Learn to Ctrl-Click to copy whole words, instead of double-clicking.


L. Spiro



[EDIT]
You replied while I was typing, but it is thought for food.
[/EDIT]

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Quote:Original post by Shadeirou
In my experience, separating classes into .h and .cpp files compiles much slower than just declaring the class and implementation in the .h.


Either:

1. your build is faulty and you don't realise it yet
2. the projects you work on are small
3. or you spent most of your time editing headers when the code was separated in the usual fashion anyway
Quote:Original post by the_edd
Quote:Original post by Shadeirou
In my experience, separating classes into .h and .cpp files compiles much slower than just declaring the class and implementation in the .h.


Either:

1. your build is faulty and you don't realise it yet
2. the projects you work on are small
3. or you spent most of your time editing headers when the code was separated in the usual fashion anyway


What he says.

My project would take exponentially more time to compile when putting everything in header files. When you use a bunch of .c/.cpp files, each source file is compiled to an object .o file. This is only recompiled when something changes in the source file. So a recompile of ~100 source files might be done under a second if just one source file changed.

I dispice how templated classes / member functions and inlined (member) function must be in the header file. I see that it cannot be avoided, but it makes for long compile times when you change the templated class when many other source files depend on it. When you even put unnecessarily code in the header file ... currently my library takes ~30 seconds to compile (relatively fast I guess when compared to most big libraries), I don't feel like recompiling everything for every change.

Even the smallest functions I put in a separate source file, though there can be debate of making those functions (often get/set) inlined...
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora

This topic is closed to new replies.

Advertisement