Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why put a class declaration and definition in two separate files in C++?

Tags:

c++

I'm just wondering, what is the whole point of separating classes into an .h and a .cpp file? It makes it harder to edit, and if your class won't be compiled into a .lib or .dll for outside use, what's the point?

Edit: The reason I'm asking is that the Boost libraries put everything in an .hpp file, (most of the libraries anyways), and I wanted to know why it is separated in most of the other code that I see.

like image 538
LM. Avatar asked May 17 '09 02:05

LM.


People also ask

What is an advantage of using separate files for classes?

It is nice to avoid an extra set of naming conventions, by making each file name consistent with a C++ namespace or class names one avoids the need to think up new names or convert from one convention to another.

Should classes be in separate files?

The answer is yes.

What is the difference between class declaration and class definition?

Difference Between Definition and Declaration It aims at determining the overall values stored in a class, a function, or a variable. It aims at specifying the name of any given class, function, variable, etc. Definition allocates memory to an entity. A declaration does not allocate memory to the entities.

Which two files are usually defined for a class?

C++ classes (and often function prototypes) are normally split up into two files. The header file has the extension of . h and contains class definitions and functions. The implementation of the class goes into the .


5 Answers

C++ has something called the One Definition Rule. It means that (excluding inline functions), definitions can only appear in one compilation unit. Since C++ header files are just "copy and pasted" at every include file, now you are putting definitions in multiple places if you just put the definitions in header files.

Of course, you may say, why not make everything inline. Well, if the compiler respects your inline suggestion, code for long functions will be replicated at every call site, making your code excessively large, and possibly causing thrashing, cache issues, and all sorts of unfun stuff.

On the other hand, if the compiler does not listen to you, and doesn't inline anything, now you have 2 problems: 1) you don't know which translation unit got your classes definitions, and 2) the compiler still has to wade through your definitions every time you #include them. Moreover, there's no easy way to make sure you haven't accidentally defined the same method twice, in 2 different headers, differently.

You also get a circular dependency issue. For a class to invoke another class's method, that class needs to be declared first. So if 2 classes need to invoke each other's methods, each must be declared before either can be defined. There is no way to do this with declarations and definitions in one file.

Really, it's how the language and parser were built. It's a pain, but you just have to deal with it.

like image 93
rlbond Avatar answered Nov 01 '22 17:11

rlbond


Well, one of the benefits of having the code this way is that it reduces compile time.

Let's say you have these files on your project:

  • a.h
  • a.cpp
  • b.cpp

If you already have a.cpp compiled into an object file a.o, then if you include a.h in b.cpp, compilation should be quicker because parser won't have to deal with the whole declaration/definition of a.

like image 35
Pablo Santa Cruz Avatar answered Nov 01 '22 17:11

Pablo Santa Cruz


Boost doesn't inline all of it's code; it inlines template definitions for classes it expects its consumers to instantiate, like shared_ptr. Many libraries have sections that need to be compiled separately, like boost::serialization and program_options.

Inlining can have severe negative effects as the size of your code base increases. It increases the coupling between your components, not to mention nuking your compile time (which boost does for plenty of other reasons :). Effectively, all of your translational units would have almost a complete copy of the program, and a tiny change would cause you to rebuild/retest everything. On some projects, this could take many, many hours.

I've never really noticed it being harder to edit; in my experience, it makes it easier because of the clear separation of interface and implementation, and I know which file to go to find what I'm looking for.

like image 25
Todd Gardner Avatar answered Nov 01 '22 19:11

Todd Gardner


Because even within your DLL other classes will use your class. Those files must see the class declaration at compile time, by including the .h. They must not see the definition or there will be multiple definitions of the class functions.

like image 34
Steve Fallows Avatar answered Nov 01 '22 17:11

Steve Fallows


Your edit re: Boost makes an important distinction. Template classes are almost always defined in headers because of the way the compiler and linker work in the current C++ standard. You will find most template libraries (not just Boost) are implemented in header files for the same reason.

like image 29
sean e Avatar answered Nov 01 '22 17:11

sean e