Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 203
ICoffeeConsumer Avatar asked Jan 23 '13 17:01

ICoffeeConsumer


2 Answers

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.

like image 198
juanchopanza Avatar answered Sep 21 '22 10:09

juanchopanza


Most header files should be wrapped in an include guard:

#ifndef MY_UNIQUE_INCLUDE_NAME_H
#define MY_UNIQUE_INCLUDE_NAME_H

// All content here.

#endif

This way, the compiler will only see the header's contents once per translation unit.

like image 26
aschepler Avatar answered Sep 19 '22 10:09

aschepler