C++ class redefinition error - Help me understand headers and linking

ICoffeeConsumer picture ICoffeeConsumer · Jan 23, 2013 · Viewed 11.7k times · Source

I started writing a simple interpreter in C++ with a class structure that I will describe below, but I quit and rewrote the thing in Java because headers were giving me a hard time. Here's the basic structure that is apparently not allowed in C++:

main.cpp contains the main function and includes a header for a class we can call printer.h (whose single void method is implemented in printer.cpp). Now imagine two other classes which are identical. Both want to call Printer::write_something();, so I included printer.h in each. So here's my first question: Why can I #include <iostream> a million times, even one after the other, but I can only include my header once? (Well, I think I could probably do the same thing with mine, as long as it's in the same file. But I may be wrong.) I understand the difference between a declaration and an implementation/definition, but that code gives me a class redefinition error. I don't see why. And here's the thing that blows my mind (and probably shows you why I don't understand any of this): I can't just include printer.h at the top of main.cpp and use the class from my other two classes. I know I can include printer.h in one of the two classes (headers) with no trouble, but I don't see why this is any different than just including it before I include the class in main.cpp (as doing so gives me a class not found error).

When I got fed up, I thought about moving to C since the OOP I was using was quite forced anyway, but I would run into the same problem unless I wrote everything in one file. It's frustrating to know C++ but be unable to use it correctly because of compilation issues.

I would really appreciate it if you could clear this up for me. Thanks!

Answer

juanchopanza picture juanchopanza · Jan 23, 2013

Why can I #include a million times, even one after the other, but I can only include my header once?

It is probably because your header doesn't have an include guard.

// printer.h file
#ifndef PRINTER_H_
#define PRINTER_H_

 // printer.h code goes here

#endif

Note that it is best practice to chose longer names for the include guard defines, to minimise the chance that two different headers might have the same one.