Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Header and CPP includes

quick question.

I am trying to get C++ nailed down, and today I spent hours with a double definition linker error("this has already been defined!") and I finally realised it's because I had the layout as such:

  • main.cpp

    #include Dog.cpp
    
  • Dog.cpp

    #include Dog.h
    
  • Dog.h

    // (Dog class and prototype of test function)
    

And now that I've cleared that up by including the Dog.h instead of the Dog.cpp in the main.cpp.

By including the .h file, does the .cpp file with the identical prefix get compiled with the program?

I was astounded when the program ran with only the .h included and no references whatsoever to Dog.cpp. I spent ages Googling but no answers really helped me understand what was going on.

Edit: I forgot to add that I prototyped in the .h, and defined the function for the class in the .cpp and that's what gave me the "already defined" error.

like image 419
ThomasuDesu Avatar asked Feb 22 '23 19:02

ThomasuDesu


1 Answers

By including the .h file, does the .cpp file with the identical prefix get compiled with the program? I was astounded when the program ran with only the .h included and no references whatsoever to Dog.cpp.

No.

Your program is built in phases.

  • For the compilation phase, only declarations are needed in each translation unit (roughly equivalent to a single .cpp file with #includes resolved). The reason that declarations even exist in the first place is as a kind of "promise" that the full function definition will be found later.

    g++ -c Dog.cpp               # produces `Dog.o`
    g++ -c main.cpp              # produces `main.o`
    
  • For the linking phase, symbols are resolved between translation units. You must be linking together the result of compiling Dog.cpp and of compiling main.cpp (perhaps your IDE is doing this for you?), and this link process finds all the correct function definitions between them to produce the final executable.

    g++ Dog.o main.o -o program  # produces executable `program`
    

    (Either that, or you actually haven't got to the link phase yet, and merely have an object file (Dog.o); you can't execute it, partially because it doesn't have all the function definitions in.)

The two phases can be done at the same time, with the "shorthand":

g++ Dog.cpp main.cpp -o program  # compiles, links and produces executable
like image 57
Lightness Races in Orbit Avatar answered Mar 06 '23 17:03

Lightness Races in Orbit