32

I was always confused about header files. They are so strange: you include .h file which doesn't include .cpp but .cpp are somehow compiled too.

Recently I joined a team project, and of course, both .h and .cpp are used.
I understand that this is very important, but I can't live with copy-pasting every function declaration in each of multiple classes we have.

How do I handle the 2-file convention efficiently?
Are there any tools to help with that, or automatically change one file that looks like example below to .h and .cpp? (specifically for MS VC++ 2010)

class A
{
...
    Type f(Type a,Type b)
    {
        //implementation here, not in another file!
    }
...
};

Type f(Type a)
{
     //implementation here
}
...
18
  • 12
    This question could go a couple of ways .. "Why do we need headers when using c++" or, "Do you think a modern language that is meant to be compiled should be using headers?" As it is, it has 'What do I do" and "hate" in the title, which sets off a plethora of flags.
    – Tim Post
    Jan 10, 2011 at 16:29
  • 8
    Your question makes it seem like you don't understand C++, or how whatever system you use compiles it. Learn to use it properly, and then ask more subjective questions. Jan 10, 2011 at 16:35
  • 39
    Your first sentence indicates that you don't "understand everything about headers". Including a .h file does not cause the corresponding .cpp file to be "somehow compiled too". You compile .cpp files independently in their own right. If you haven't compiled the corresponding .cpp, then the inclusion of a header without a corresponding object file will cause the linker to fail. Jan 10, 2011 at 17:50
  • 6
    What to do? Find another language if it bugs you that much. Jan 10, 2011 at 19:23
  • 5
    About the "can't live with copy-pasting": Whenever one updates a function, one has to update all places where it is called anyway. As the callers are much harder to find than the declaration in the header file, updating the header is just a minor detail.
    – Sjoerd
    Jan 10, 2011 at 22:53

8 Answers 8

3

You could use Lzz. It's a command line tool that takes declarations written in a C++ syntax and generates the header and source files.

2
  • Substituting auto-generation for a lack of programmer skill and knowledge is a bad solution. Jun 30, 2020 at 15:10
  • 1
    Also you may not want to to expose in the header the whole stuff you wrote in your cpp.
    – Amessihel
    Jun 30, 2020 at 15:16
23

Writing More Refactoring Friendly C++

In C++ you don't have to use headers at all. You can define the whole object in one file just as you would with C# or Java. C developers will commonly only keep external calls in a header file. All the internal calls would be defined in the .c file. By the same token, you can reserve your C++ .h files for the classes/interfaces (pure virtual abstract classes)/etc. that are intended to be shared outside the DLL. For internal classes/structs/interfaces, etc. you would simply include the .cpp file you need:

#include<myclass.cpp>

This doesn't seem to be the most popular approach, but it is legal C++. It would definitely be a possibility for all your internal code. This allows the internal code and set of classes to change a lot more radically while providing a more stable interface for code outside your library/executable to interact with.

Having your whole class inside one file will make it easier to do what you want. It won't solve the problem of renaming a method and having to search down every place that method is called, but it will make sure you have more intelligable error messages. Nothing worse than having your header declare a method one way, but you implement it differently. Other code that calls the header file will compile properly and you'll get a link exception, while the implementation file will be the one that complains that the method wasn't defined. When you define every method in place (in the actual class declaration), you'll get the same error message no matter what file includes it.

You may also want to look at this question: Good refactoring tools for C++

How C/C++ Resolves Header/Implementation Files

At the base C level (and C++ is built on that foundation), the header files declare the promise of a function/struct/variable which is enough to allow a compiler to create the object file. Similarly C++ header files declare the promise of functions, structs, classes, etc. It is this definition that the compiler uses to reserve space in the stack, etc.

The the .c or .cpp files have the implementation. As the compiler converts each implementation file to an object file, there are hooks to unimplemented concepts (what was declared in the header). The linker ties the hooks to the implementations in other object files and creates a larger binary that includes all the code (shared library or executable).

VS Specific

As to working with those in Visual Studio, there are some wizards that help make things a bit easier. The new class wizard will create your matching pair of header and implementation files. There is even a class browser feature that will allow you declare new methods. It will inject the definition in the header and the implementation stub in the .cpp file. Visual Studio has had those features for more than a decade (as long as I've used them).

6
  • 1
    The problem is, I'm heavily modifying the classes all the time, not just adding new functions, etc Jan 10, 2011 at 16:18
  • 6
    @BlaXpirit: So, why are you heavily modifying the classes all the time? One of the ideas behind OO design is to have a lot of fairly stable building blocks. If I were heavily modifying classes, I'd like a more dynamic language, like Common Lisp or Python. Jan 10, 2011 at 16:34
  • 6
    That's what I'm doing. I'm improving/modifying the "building blocks" and adding new ones Jan 10, 2011 at 16:36
  • C++ has never been refactoring friendly. The concept of refactoring didn't gain momentum until there were tools that made it really easy to do in Java IDEs. NOTE: those features were there for Smalltalk developers, and other languages, but it didn't become mainstream until it was available for a lot of people. So far I have yet to see someone intelligently implement that for C++. Perhaps Resharper from JetBrains? I know it does C# and VB code, but I'm not sure if it will give you C++ refactoring. Jan 10, 2011 at 17:10
  • @Berin: I went looking for C++ refactoring tools a year or two ago, and found two things. They were fairly pricey at the time, and I didn't see trial versions, so I don't know what they did. Moreover, one worked with emacs only, which would limit its effectiveness in a Visual Studio shop. Jan 10, 2011 at 18:18
21

Become a Java developer.

If you really must carry on developing in C++, you could try using an IDE. Often they offer some mechanism by which you can add a method to a class, and it automagically places the declaration in the .h file and the definition in the .cpp file.

11
  • 4
    kthx, I somewhat know Java, but you can't make low-level Win32 DLLs with it, can you? Jan 10, 2011 at 16:53
  • 52
    I don't know why, but 'Become a Java developer' somehow sounds like an insult :D. Jan 10, 2011 at 16:54
  • 3
    If you want to do low level, forget everything about 'easy languages'. Low level costs sweat and tears. Jan 10, 2011 at 18:56
  • 10
    Not a particularly helpful answer.
    – ChrisF
    Jan 10, 2011 at 19:43
  • 3
    @OliverWeiler I don't perceive "become a Java developer" as an insult. I program both in C++ and Java, but my preference by far is Java because it's so much easier to sit down and bang out code that works (and more portable). If you for some reason detest the existence of header files, trying Java may be the right choice (though it's odd you would hate header files; I'd consider a change in IDE). Jul 29, 2014 at 21:54
10

You could be interested in the makeheaders program from Hwaci (those who do SQLite and Fossil).

Also have a look at how fossil is built to have an idea.

3
  • 6
    The asker still needs to understand the relationship between .h and .cpp quite well.
    – Job
    Jan 10, 2011 at 16:13
  • 3
    I understand the basics. The answer seems to be just what I need. Jan 10, 2011 at 16:20
  • @OlehPrypin: If you think "you include .h file which doesn't include .cpp but .cpp are somehow compiled too" then you don't understand the very basics of this. Jun 30, 2020 at 23:21
6

When you write the first lines of a new class, it usually is because you need it in one place only at that time. At a later time, it might be used at more places, but initially it usually isn't.

Many of my classes start at the top of the current .cpp file. When it has stablized enough to use it in multiple places, I cut-paste it to a header. Though often the class disappears as fast as it appeared.

5

The Header (.h) file describes the interface to the code, because that's the only bit that other code gets to see.

The Source (.cpp) file provides the implementation of the code that nobody else needs to know about.

you include .h file which doesn't include .cpp ...

Correct.

As a consumer of this code, you only need the Header file so that the compiler knows what's available in that code for you to work with. The C++ source code is not used in any way, shape or form at this point (or, at least, it shouldn't be).

... but .cpp are somehow compiled too.

Yes that are, but completely separately.

The .cpp file of a module/library that you are using is compiled into an Object file (.o / .dll) by the Developer of that library. That object file will contain entry points that are the same "shape" as those described in the Header file.

You will need that Object file when you come to link your finished executable, at which point the Linker may grab the contents of the Object file and embed it into your executable (that's for static linking; dynamic linking gets more complicated)
Basically the linker has to "joins the dots" between the entry points that your code expects to be able to call, based on what it saw in the Header file, and what's actually in the library itself.

-2

As a suggestion to help handle C++ header files, is common to use them without file extension or file suffix, such as "GCC" libraries does.

If this is your case, I suggest to use a ".hpp" (or unleast ".hxx") file extension or file suffix.

You may have to configure your compiler, developer enviroment, or Built program.

2
  • 4
    Are you talking about how when you include a file like #include <iostream>? Those aren't just for the GCC library. In fact, its defined in the 1997 C++ standard, section 17.3.1.2. I would avoid naming files like that. You can, but the reason the C++ standard library did that was probably to avoid naming conflicts. I actually find it really weird when compilers automatically add a '.h' when you include a header, it seems pretty unstandard to me. And I don't ever see anyone name headers without suffix except for the c++ standard library.
    – vedosity
    Feb 14, 2011 at 21:29
  • 1
    Also, I should note, all of the compilers that I have used, except for borland (which I hate so very much), don't automatically add a '.h' or '.hpp' or '.hxx' when you try to include a file with no suffix. Don't expect #include <someclass> to be read as #include <someclass.hpp> on all compilers. Your code will break.
    – vedosity
    Feb 14, 2011 at 21:49
-4

Become a Swift developer. No header files. Except if you say to yourself “I wish I could see only the things that a user of this file needs”, you tell the IDE to show the interface of the file, with all implementations and with all non-public functions gone. (One better than C++ header files containing inline definitions and private methods).

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