Is is a good practice to put the definition of C++ classes into the header file?

c++ class header file and implementation
c++ multiple files with classes
c++ header files
class in hpp file
declare a class in header file
c++ class implementation
are classes defined in header files c++
c++ define header file

When we design classes in Java, Vala, or C# we put the definition and declaration in the same source file. But in C++ it is traditionally preferred to separate the definition and declaration in two or more files.

What happens if I just use a header file and put everything into it, like Java? Is there a performance penalty or something?

The answer depends on what kind of class you're creating.

C++'s compilation model dates back to the days of C, and so its method of importing data from one source file into another is comparatively primitive. The #include directive literally copies the contents of the file you're including into the source file, then treats the result as though it was the file you had written all along. You need to be careful about this because of a C++ policy called the one definition rule (ODR) which states, unsurprisingly, that every function and class should have at most one definition. This means that if you declare a class somewhere, all of that class's member functions should be either not defined at all or defined exactly once in exactly one file. There are some exceptions (I'll get to them in a minute), but for now just treat this rule as if it's a hard-and-fast, no-exceptions rule.

If you take a non-template class and put both the class definition and the implementation into a header file, you might run into trouble with the one definition rule. In particular, suppose that I have two different .cpp files that I compile, both of which #include your header containing both the implementation and the interface. In this case, if I try linking those two files together, the linker will find that each one contains a copy of the implementation code for the class's member functions. At this point, the linker will report an error because you have violated the one definition rule: there are two different implementations of all the class's member functions.

To prevent this, C++ programmers typically split classes up into a header file which contains the class declaration, along with the declarations of its member functions, without the implementations of those functions. The implementations are then put into a separate .cpp file which can be compiled and linked separately. This allows your code to avoid running into trouble with the ODR. Here's how. First, whenever you #include the class header file into multiple different .cpp files, each of them just gets a copy of the declarations of the member functions, not their definitions, and so none of your class's clients will end up with the definitions. This means that any number of clients can #include your header file without running into trouble at link-time. Since your own .cpp file with the implementation is the sole file that contains the implementations of the member functions, at link time you can merge it with any number of other client object files without a hassle. This is the main reason that you split the .h and .cpp files apart.

Of course, the ODR has a few exceptions. The first of these comes up with template functions and classes. The ODR explicitly states that you can have multiple different definitions for the same template class or function, provided that they're all equivalent. This is primarily to make it easier to compile templates - each C++ file can instantiate the same template without colliding with any other files. For this reason, and a few other technical reasons, class templates tend to just have a .h file without a matching .cpp file. Any number of clients can #include the file without trouble.

The other major exception to the ODR involves inline functions. The spec specifically states that the ODR does not apply to inline functions, so if you have a header file with an implementation of a class member function that's marked inline, that's perfectly fine. Any number of files can #include this file without breaking the ODR. Interestingly, any member function that's declared and defined in the body of a class is implicitly inline, so if you have a header like this:

#ifndef Include_Guard
#define Include_Guard

class MyClass {
public:
    void DoSomething() {
        /* ... code goes here ... */
    }
};

#endif

Then you're not risking breaking the ODR. If you rewrite this as

#ifndef Include_Guard
#define Include_Guard

class MyClass {
public:
    void DoSomething();
};

void MyClass::DoSomething()  {
    /* ... code goes here ... */
}

#endif

then you would be breaking the ODR, since the member function isn't marked inline and if multiple clients #include this file there will be multiple definitions of MyClass::DoSomething.

So to summarize - you should probably split up your classes into a .h/.cpp pair to avoid breaking the ODR. However, if you're writing a class template, you don't need the .cpp file (and probably shouldn't have one at all), and if you're okay marking every single member function of your class inline you can also avoid the .cpp file.

Object Oriented Programming with C++: OOPC, Of course, you can write anything in the header files, i.e. both declarations and definitions. It is only a good practice to put declarations in header files and  In C++, separate compilation of code modules (.c or .cpp files) require the function prototypes to be defined prior to usage. If you want to use classes or methods defined somewhere else, you have to import the .h files to get their definition. At the end, the linker makes sure all promises made in the .h files can be fulfilled by all c/cpp files.

The drawback of putting definition in header files is as follows:-

Header file A - contains definition of metahodA()

Header file B - includes header file A.

Now let us say you change the definition of methodA. You would need to compile file A as well as B because of the inclusion of header file A in B.

8.9, Traditionally, the class definition is put in a header file of the same name as the class, into declaration (header) and implementation (code file) is not only good form, in the header to keep the code shorter, you shouldn't do that in practice. A simple practice in C or C++ programs is that we keep all the constants, macros, system wide global variables, and function prototypes in the header files and include that header file wherever it is required.

The biggest difference is that every function is declared as an inline function. Generally your compiler will be smart enough that this won't be a problem, but worst case scenario it will cause page faults on a regular basis and make your code embarrassingly slow. Usually the code is separated for design reasons, and not for performance.

Sams Teach Yourself C++ in 24 Hours, Where to Put Class Declarations and Method Definitions Each function that you Like other functions, the definition of a class method has a function header and a Most C++ compilers want that file to end with .C, or .CPP. This book uses . to put the declaration in the source code file, it is not good programming practice. Two words: Ockham's Razor. Keep one class per file with the corresponding header in a separate file. If you do otherwise, like keeping a piece of functionality per file, then you have to create all kinds of rules about what constitutes a piece of functionality. There is much more to gain by keeping one class per file.

In general, it is a good practice to seperate implementation from headers. However, there are exceptions in cases like templates where the implementation goes in the header itself.

Applied Pattern Recognition: Algorithms and Implementation in C++, It is good practice to put all data members into the private section of a class and to be put into a header file ( . h ) ; definitions should be put into several modules ( . C ) which are independent of each other in the sense that they do not contain  Perhaps from C, one way in which people sometimes separate interface from implementation in C++ is to use function signatures etc., in a header file, as an interface definition. However, that is not the only way to define an interface in order to separate it from implementation.

Two particular problems with putting everything in the header:

  1. Compile times will be increased, sometimes greatly. C++ compile times are long enough that that's not something you want.

  2. If you have circular dependencies in the implementation, keeping everything in headers is difficult to impossible. eg:

    header1.h

    struct C1
    {
      void f();
      void g();
    };
    

    header2.h

    struct C2
    {
      void f();
      void g();
    };
    

    impl1.cpp

    #include "header1.h"
    #include "header2.h"
    
    void C1::f()
    {
      C2 c2;
      c2.f();
    }
    

    impl2.cpp

    #include "header2.h"
    #include "header1.h"
    
    void C2::g()
    {
      C1 c1;
      c1.g();
    }
    

Through C to C++: A Complete Programming Course, The data declarations for the class string 1 declare a pointer *text to the first character in a string, represented by an though it is not good practice to have public data. In C++ it is common practice to place the class definitions in a header file. The classes are very tightly linked. E.g., if a class defines its own iterator, then it might be appropriate to put that iterator class in the same file as the class that it's used to iterate over. One of the classes is for public consumption, and the remaining classes are used to implement it.

A Natural Introduction to Computer Programming with C++, All classes and their member functions are in header files (.h files), and included work on the development project, it is good practice to put different classes in  The default header file that comes with the C compiler is the stdio.h. Including a header file means that using the content of header file in your source program. A straightforward practice while programming in C or C++ programs is that you can keep every macro, global variables, constants, and other function prototypes in the header files.

C++ Best Practice – Designing Header Files, C++, and its close relatives C and C++/CLI, have a compilation model that was Frequently, a header file will bring in a class (or class template) definition when  For instance in derived classes you can pretty much rely on includes of the base. Make your own include which just includes a bunch of other includes. But be careful with that. It is a good practice for huge includes that do not change often. This is also not very common practice on posix systems.

Is it a bad idea to define classes in header files in C++?, Victor Volkov, Some experience (C++, some C#, Python, a bit of tinkering with other an implementation file that contains all the methods for a set of header files? No, this is standard practice (to define classes in C++ header files).

Comments
  • Then you defeat the entire purpose of separating interface from implementation.
  • Not only that, you will end up compiling your whole application as one big source file, and every little change will cause a recompilation of your complete application.
  • Also see: What are the advantages and disadvantages of separating declaration and definition as in C++?
  • Terminology. In C++, this is a class declaration: class Foo;. This is a class definition: class Foo { void foo(); int bar(const char*);};. In C++, one usually puts class definitions in header files, and the decision to make is where to put the definitions of the member functions.
  • @Ed S.: no you don't. The standard template containers and algorithms have complete definitions in header files, and yet they manage to logically separate interface from implementation fine. The interface is in the standard, not in the header files. Perhaps from C, one way in which people sometimes separate interface from implementation in C++ is to use function signatures etc., in a header file, as an interface definition. However, that is not the only way to define an interface in order to separate it from implementation. I doubt it's the most common way in C++ (well, I hope it isn't).