5

I have been working a lot with Java, and C++ is right down confusing.

In Java you have class files, at first I supposed it's the equivalent to header files in C++, like so:

#ifndef PROGRAM_H
#define PROGRAM_H

#include <iostream>
#include <string>

class Program {
private:
    std::string name, version, author;

public:
    Program(std::string name, std::string version, std::string author) {
        this->name = name;
        this->version = version;
        this->author = author;
    }

    std::string toString() {
        return name + " " + version + " - by " + author + "\n";
    }

} MainProgram("program", "2.0a", "foo bar");

#endif

I've just read that I should separate my classes into two files, the header to define the class, and the .cpp to implement the class.

Should I really do it to each class? because the header class above compiles just fine, and it seems too simple to really separate it to two files, perhaps maybe only large classes should be separated by convention? Any suggestions?

julian
  • 4,634
  • 10
  • 42
  • 59
  • 4
    Tip: Stop Thinking in terms of how Java relates to C++. I know it's difficult as a beginner, but they are very different languages, and you will end up confusing yourself even more. On Topic: Yes, you should separate interface from implementation. – Ed S. Jul 27 '15 at 23:50
  • 6
    That being said, it is not REQUIRED to break up the code into separate files if you don't want to. You CAN implement it like shown. Standard libraries like STL and Boost are based on header-only principles (of course, they are heavily templated, which requires such an implementation). At the very least, if you want to break up interface from implementation while maintaining header-only semantics, you can move the implementation code into `.i`/`.icc` files that are `#include`'d at the bottom of the `.h` files. – Remy Lebeau Jul 27 '15 at 23:58
  • 1
    Please do not write `using namespace std;` in a header file. – aschepler Jul 28 '15 at 00:00
  • @aschepler Oops, I remember that tip! well how can I use strings then? it requires me to use that namespace.. – julian Jul 28 '15 at 00:01
  • @aschepler: unless it is wrapped in another namespace. – Remy Lebeau Jul 28 '15 at 00:01
  • 2
    @Israelg99: use `std::string` instead of `string`. – Remy Lebeau Jul 28 '15 at 00:01
  • 1
    In my opinion, it is sometime awkward or near impossible in c++ to NOT to separate header and implementation files, regardless of how much or little the implementation is. In other words, whether to separate or not is not an option based on need. This "barrier" may come as a surprise to programmers coming from other languages who were not "required" to separate. – thor Jul 28 '15 at 00:15

2 Answers2

6

You really should separate your declarations and and definitions (or interfaces and implementations) in .h and .cpp pairs.

The reasoning behind this separate-compilation model becomes clear when you work with anything more than a handful of interdependent source files. Since a header can potentially be #include'd all over the place, the separation allows you to make changes to the implementation without needing to recompile all code that is utilizing the interface.

The savings of time can be significant, especially when making a bunch of quick edits to a single file.

(The notable exception to the convention of .h/.cpp pairings is for templated classes - which do indeed just live in a .h file - but that's a whole other story).

cowsock
  • 91
  • 3
  • Thanks for the suggestion, sounds very reasonable and I didn't know about the exception of templates classes, I suppose it's more portable to reside them just in header files. – julian Jul 28 '15 at 00:06
  • 2
    @Israelg99 The compiler takes the template and builds a specialization of it for whoever uses the template. For this to work, everyone using the template has to have a copy of the template, and normally that means a header file. If the template's implementation changes, whoever used the template has to rebuild their specialization of it anyway, so the compilation time gain from separating out the implementation is lost. If you are going to lose, you might as well keep the code tidy and keep it all in one place. – user4581301 Jul 28 '15 at 00:40
  • @user4581301 Thanks for the info! It looks like the convention of .h/.cpp pairings, is more of a compilation time gain than a convention, so when the compilation time gain is lost, you rather just keep it all in one tidy place and screw the convention :) Anyway, thanks again for the useful info! – julian Jul 28 '15 at 00:49
3

Short answer: YES. In this way, if you modify a class implementation (not interface), the clients that use your class don't have to recompile, but only to link the new object file corresponding to the modified implementation.

Long answer: read about the C++ compilation model.

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252