What Are the Advantages and Disadvantages of Implementing Classes in Header Files

What are the advantages and disadvantages of implementing classes in header files?

Possible advantages of putting everything in header files:

  • Less redundancy (which leads to easier changes, easier refactoring, etc.)
  • May give compiler/linker better opportunities for optimization
  • Often easier to incorporate into an existing project

Possible disadvantages of putting everything in header files:

  • Longer compile/link cycles
  • Loss of separation of interface and implementation
  • Could lead to hard-to-resolve circular dependencies
  • Lots of inlining could increase executable size
  • Prevents binary compatibility of shared libraries/DLLs
  • Upsets co-workers who prefer the traditional ways of using C++

C++: Drawbacks to writing whole classes in Header files for small projects?

is there any compelling reason to follow the "file.cpp" for every "file.h" setup for a small project where compile time and interface/implementation separation are not priorities?

Nope; there's nothing wrong with defining classes and functions in header files, especially not in small projects where compile times aren't a concern.

For what it's worth, my current, in-progress hobby project has 33 header files and a single .cpp file (not including unit tests). That is largely due to just about everything being a template, though.

If you have a huge software project or if you need to encapsulate your code into a library and actually need the modularity, then it might make sense to split code out of a header file. If you want to hide some implementation detail (e.g., if you have some ugly header that you don't want to include elsewhere in your project--WinAPI headers, for example), then it makes sense to split code into a separate source file to hide those details. Otherwise, it may just be a lot of work for not a lot of gain.

Advantages/Disadvantages of Header Files

Taken from a related blog post by Eric Lippert, who puts it very well:

I would have asked the equivalent
question why does C++ need header
files
? Header files seem like a huge
potential point of failure; all the
time I edit C++ code and change the
signature of a method; if I forget to
update the header file, then the code
doesn’t compile and often gives some
cryptic error message. Hopefully this
large cost actually buys you
something.

It buys the compiler writer one thing,
and the user one thing.

What it buys the user is that you can
compile each individual “cpp” file
into a “obj” file independently,
provided that you have all the
necessary headers. All the information
necessary to generate the bodies that
are in a given cpp file can be gleaned
from the set of headers. This means
that the build system can recompile
just those cpp files that changed,
provided that no header changed.

What it buys the compiler writer is
that every file can be compiled in
“one pass”. Because every type and
method declaration is processed before
its first usage, the compiler can
simply start from the top of the file,
pull in all the included headers, and
proceed from the top down, spitting
out the obj file as it goes, never
having to go back and revisit
something its seen already.

This is in contrast to languages such as C# (about which the blog post is) and Java, which is a pretty close relative.

What are the benefits and drawbacks of using header files?

I'm not sure exactly what question you are asking, so I will try to rephrase it:

What is the benefit of putting public information in a separate (header or interface) file, as opposed to simply marking information as public or private wherever it appears?

The main benefit of having a separate interface or header file is that it reduces the cognitive load on the reader. If you are a trying to understand a large system, you can tackle one implementation file at a time, and you need to read only the interfaces of the other implementations/classes/modules it depends on. This is a major benefit, and languages that do not require separate interface files (such as Java) or cannot even express interfaces in separate files (such as Haskell) often provide tools such as Doxygen or Haddock so that a separate interface, for people to read, is generated from the implementation.

I strongly prefer languages like Standard ML, Objective Caml, and Modula-2/3, where there is a separate interface file available for scrutiny. Having separate header files in C is also good, but not quite as good because in general, the header files cannot be checked independently by the compiler. (C++ header files are less good because they allow private information, such as private fields or the implementations of inline methods, to leak out into the header files, and so the public information becomes diluted.)

It's folklore in the language-design world that for typical statically typed languages, only about 10% of the information in a module is public (measured by lines of code). By putting this information in a separate header file, you reduce the reader's workload by roughly a factor of ten.

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

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.

Using C++ headers (.h) vs headers plus implementation (.h + .cpp), what are the disadvantages?

There's a few ways that separating the two help in C++. Firstly, if you'd like to update a library without changing an interface then having the code in the C++ file means that you simply can update the library rather than the library plus the headers. Secondly it hides the implementation. That is, it forces people to look at your class only in terms of the interface, the thing that should concern them if the code is well written. Finally, there's a sort of asthetic cleanness with interface + documentation that comes with this separation. It's something you have to get used to but after a while it'll feel natural (opinion.)

Pros/ Cons of using one big include file

I would say that in general this is a bad idea for several reasons:

  • It gives you poor encapsulation: clients should just pull in the headers they need. With this approach the inclusion will pull in everything, which as Alok mentions will increase build time and sensitivity to rebuilds
  • There's no distinction between interface classes and implementation classes, ie those that clients of your library use and ones that are used internally by this library that clients don't need to (and perhaps shouldn't) see
  • If any of your headers define macros then these may now 'leak' into any other code that includes the header, which may be undesirable. Anyone who's ever had to type #undef MIN will know this pain.
  • There's a possibility of recursive inclusion if you have several classes that need to be aware of each other, so it may be sensitive to the order of inclusion or you'll get include cycles

I think though there is one instance where it may be acceptable, which is if your library only provides a few classes/functions that are intended to be called by clients, and all the rest are just internal classes used by the implementation. So clients can just include mylib.h and that's all they need to worry about. This also makes it easier if you want to compile your library as a static library as you can just distribute the library and one header.

Need help in understanding concept: why declare a function in header but define it in source file?

why declare a function in header but define it in source file?

The declaration is needed to call the function. It goes in the header so that any file which wants to call the function can include the header and have the declaration available.

There can only be one definition, so it goes in just one source file.

With the guard, we won't have multiple definitions, right?

There would be one definition in each source file that included the header. The guard prevents multiple inclusions from the same source file, but not inclusions from different source files.



Related Topics



Leave a reply



Submit