3

When creating a C++ class what is best practice>

  • Put the entire class definition and member functions in a header file
  • Put the class definition and function declarations in the header file and put the function definitions in a separate source file
  • Put the entire class definition and declare member functions in a source file?

I realize you can do it any of those three ways, but I am wondering if there is a preferred/fastest way. Any information would be great.

  • You can't put the entire class definition in a source file if you plan to use the class outside that file. – Sebastian Redl Jun 2 '16 at 11:51
9

It depends, as usual.

Generally, it's best practice to split each class into a header (.h or .hpp) and source (.cpp) file, where you put everything you can in the source file*, because it considerably speeds up building your program. This is incredibly important in real world development because large projects can take anywhere from 15 minutes to several hours to fully recompile and link. If you change anything in a source file the compiler only needs to recompile that cpp file into an object file and link the programs that include this object file. If you change anything in a header file, the compiler needs to recompile all cpp files that include that header and link all the programs that include any of these object files.

If the class is lightweight and very unlikely to change it's usually better to have it all in a header file. An example would be a class that serves as a strongly typed ID and only has a constructor and a comparison operator. Using only a header file keeps the code simpler and easier to read, and in this special case doesn't harm compile time because the class will "never" change.

If the class is a template it is usually not possible to put anything in a cpp file (unless we use template specialization), but it is often convention to place the definitions below the class declaration in the header file, using the inline keyword to allow compilation.


*You can put even more in the source file if your project suffers strongly from header dependencies and the resulting compile time: pImpl Idiom

2

Normally you put the class definition and the function declarations in the header file. And the function definitions in a source (*.cpp) file.

The reason to put the class definition and function declarations in the header file is so that other parts of the software can include the header and use the class and its method.
The reason to put the method definitions in a cpp-source file was that the methods should be defined only once. Modern compilers (i.e. C++-14 and above) can cope with the same method defined multiple times (given that all definitions are equal, as is the case with included header files). However, most C++ programmers expect the method definitions to be in cpp-files and only in header files when the methods should be inlined, therefore I would advise to put the methods in cpp-files.

1

This is probably subjective, but it's an interesting question. A class in C++ is used to represent several distinct concepts:

  1. An interface
  2. An object
  3. A type

An interface will involve virtual void foo() = 0 and (hopefully) no implementation. An object will bundle some state with some related methods, e.g. std::vector<int>. A type is used to control the compilation process, but has no purpose beyond this - it could be as simple as struct tag; or struct tag {}.

I believe that whether the class and methods should be split depends on which of the above categories you are using it for. An interface will move everything it can into the source file. An object is likely to be a mixture of small inline methods, written in the header, and larger functions, perhaps with dependencies, in the source. A pure type tends to be involved with templates and entirely in the header.

All that said, most forms of "best practice" amount to (compromises between) minimising duplication and minimising coupling. If we apply these goals to classes, we probably want to put any method that would pull in dependencies from elsewhere into the source file to minimise coupling, and any others into the header so we don't need to type quite so much. Writing a class entirely in a source file is great until it needs to be shared with other compilation units, but until then, go for it.

This is complicated by templates. If the class in question is templated, one is forced to choose between writing most of it in the header or explicitly instantiating it for a known set of types in a single source file. I couldn't defend it as best practice, but I tend to write templated classes entirely in header files, factoring out such type-agnostic code as exists into free functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.