Difference between implementing a class inside a .h file or in a .cpp file

33,394

Solution 1

The main practical difference is that if the member function definitions are in the body of the header, then of course they are compiled once for each translation unit which includes that header. When your project contains a few hundred or thousand source files, and the class in question is fairly widely used, this might mean a lot of repetition. Even if each class is only used by 2 or 3 others, the more code in the header, the more work to do.

If the member function definitions are in a translation unit (.cpp file) of their own, then they are compiled once, and only the function declarations are compiled multiple times.

It's true that member functions defined (not just declared) in the class definition are implicitly inline. But inline doesn't mean what people might reasonably guess it means. inline says that it's legal for multiple definitions of the function to appear in different translation units, and later be linked together. This is necessary if the class is in a header file that different source files are going to use, so the language tries to be helpful.

inline is also a hint to the compiler that the function could usefully be inlined, but despite the name, that's optional. The more sophisticated your compiler is, the better it is able to make its own decisions about inlining, and the less need it has for hints. More important than the actual inline tag is whether the function is available to the compiler at all. If the function is defined in a different translation unit, then it isn't available when the call to it is compiled, and so if anything is going to inline the call then it's going to have to be the linker, not the compiler.

You might be able to see the differences better by considering a third possible way of doing it:

// File class.h
class MyClass
{
    private:
        //attributes
    public:
       void method1(...);
       void method2(...);
       ...
};

inline void MyClass::method1(...)
{
     //implementation
}

inline void MyClass::method2(...)
{
     //implementation
}

Now that the implicit inline is out of the way, there remain some differences between this "all header" approach, and the "header plus source" approach. How you divide your code among translation units has consequences for what happens as it's built.

Solution 2

Any change to a header that includes the implementation will force all other classes that include that header to recompile and relink.

Since headers change less frequently than implementations, by putting the implementation in a separate file, you can save considerable compilation time.

As some other answers have already pointed out, yes, defining a method within a file's class block will cause the compiler to inline.

Solution 3

Yes, the compiler will try to inline a method declared directly in header file like:

class A
{
 public:
   void method()
   {
   }
};

I can think of following conveniences in separating the implementation in header files:

  1. You'll not have code bloat because of the same code getting included in multiple translation units
  2. Your compilation time will reduce drastically. Remember that for any modification in the header file compiler has to build all other files which directly or indirectly include it. I guess it will be very frustrating for any one to build the whole binary again just for adding a space in the header file.

Solution 4

Yes, defining methods inside class definition is equivalent to declaring them inline. There's no other difference. There's no benefit in defining everything in header file.

Something like that is usually seen in C++ with template classes, since template member definitions have to be included in header file as well (due to the fact that most compilers don't support export). But with ordinary non-template classes there's no point in doing this, unless you really want to declare your methods as inline.

Solution 5

Once in the past I created a module shielding from differences in various CORBA distributions and it was expected to work uniformly on various OS/compiler/CORBA lib combinations. Making it implemented in a header file made it more easy to add it to a project with a simple include. The same technique guaranteed that the code was recompiled at the same time when the code calling it required recompilation when i.e. it was being compiled with a different library or on a different OS.

So my point is that if you have a rather tiny library that is expected to be reusable and recompilable across various projects making it a header offers advantages in integration with some other projects as opposed to adding extra files to the main project or recompiling an external lib/obj file.

Share:
33,394
Jack
Author by

Jack

Busy developing games. jack(at)pixbits.com

Updated on December 20, 2020

Comments

  • Jack
    Jack over 3 years

    I was wondering which are the differences between declaring and implementing a class solely in a header file, compared with normal approach in which you protype class in the header and implement in effective .cpp file.

    To explain better what I'm talking about I mean differences between normal approach:

    // File class.h
    class MyClass 
    {
    private:
      //attributes
      public:
      void method1(...);
      void method2(...);
      ...
    };
    
    //file class.cpp
    #include "class.h"
    
    void MyClass::method1(...) 
    {
      //implementation
    }
    
    void MyClass::method2(...) 
    {
      //implementation
    }
    

    and a just-header approach:

    // File class.h
    class MyClass 
    {
    private:
      //attributes
    public:
      void method1(...) 
      {
          //implementation
      }
    
      void method2(...) 
      {
        //implementation
      }
    
      ...
    };
    

    I can get the main difference: in the second case the code is included in every other file that needs it generating more instances of the same implementations, so an implicit redundancy; while in the first case code is compiled by itself and then every call referred to object of MyClass are linked to the implementation in class.cpp.

    But are there other differences? Is it more convenient to use an approach instead of another depending on the situation? I've also read somewhere that defining the body of a method directly into a header file is an implicit request to the compiler to inline that method, is it true?

  • Pavel Minaev
    Pavel Minaev over 14 years
    The obvious point of doing this is that it's shorter. It's not really a good reason for public headers, considering the disadvantages. But for a small utility class used internally within a single module, it's perfectly fine.
  • AnT stands with Russia
    AnT stands with Russia over 14 years
    @Pavel: You seem to be talking about classes implemented (declared and defined) entrely in a cpp file (i.e. no header declaration at all). When I read the subject of the question I also initially thought that the question will be about that. But it turned out that the question is actually different. Additionally, I don't see why I should declare methods of an internal (one translation unit only) class as inline, even if it is shorter.
  • Jack
    Jack over 14 years
    infact I was talking about "request to the compiler", I know that's optional the effective inlining..
  • Steve Jessop
    Steve Jessop over 14 years
    Yes, I was repeating it just in case any new-to-C++ reader had forgotten by the time they'd waded through my first three paragraphs.
  • Steve Jessop
    Steve Jessop over 14 years
    Factually inaccurate. The question is about whether to put the function definitions in a separate translation unit. This implies several obvious differences beyond implicit inline. So saying "there's no other difference" is either totally wrong or (more likely) missing half the question.
  • AnT stands with Russia
    AnT stands with Russia over 14 years
    Well, it implies inline (excluding template cases). Whether it is an implicit inline or explicit inline doesn't appear as a critical difference to me.
  • Steve Jessop
    Steve Jessop over 14 years
    That's not what I'm quibbling about, I'm quibbling that in apparent response to the question, "which are the differences between declaring and implementing a class solely in a header file, compared with normal approach in which you protype class in the header and implement in effective .cpp file.", you've said "none other than the inline". I think you're answering "what's the difference between functions defined in or out of the class defn", instead of "what's the difference between functions defined in or out of the header".