Sign in to follow this  
Shadeirou

Separating classes to .h and .cpp

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 ><.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 ;).

Share this post


Link to post
Share on other sites
#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]

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
Quote:
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?


Absolutely. Let's say that I'm working on a large program with many hundreds of source files. I have a class that's used extensively throughout the program - for the sake of example we'll call the class "Foo" and say it's used in 100 other source files. I'm doing some updates to the internals of Foo. If I only have Foo in a header, then every time I want to test some of the changes I have to wait for the compiler to recompile all 100 of those source files where Foo is used. If Foo is implemented in separate header & source files, then as long as I don't change Foo.h a recompile of the project only needs to compile Foo.cpp and relink the executable.

Share this post


Link to post
Share on other sites
Compile time is directly proportional to number of include files preprocessor must process.
In addition, include files are typically not reusable between compilation units (.cpp).

To improve build time, reduce the number of includes. Including <iostream> brings in several hundred files. Some boost headers require expansion of thousands.

There are several common solutions to the above:
- PIMPL
- forward declarations of dependent classes
- unity build - one .cpp that includes all other .cpps
- precompile headers

Each of these has its own set of tradeoffs.

Ironically, from C++ build chain perspective, none of those would be necessary if compilers were implemented differently.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this