2

Person.h

#ifndef PERSON_H_
#define PERSON_H_

/* Person.h */

class Person {
  int age;
  std::string name;

  public:
    Person(int, std::string);
    std::string getName();
    int getAge();

};

#endif /* PERSON_H_ */

The person(int std::string) function declaration uses the std::string name, yet I have not included it in the header file. Thus, I would expect the compiler to complain about the missing symbol. Yet it compiles and runs fine! Why?

The rest of the code...

Person.cpp

#include <string>
#include "Person.h"

Person::Person(int age, std::string name)
{
  this->name = name;
  this->age = age;
}

std::string Person::getName()
{
  return this->name;
}

int Person::getAge()
{
  return this->age;
}

Main.cpp

#include <string>
#include "Person.h"

int main() {

  printFunc();

  Person chelsea_manning(5, std::string("Chelsea Manning"));

}

Also, I am new to C++, so please let me know if you see anything weird about my code / OOP.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294

1 Answers1

5

Compilation of a program begins at the top of the file that contains your main function (technically, the preprocessor is run before the program is compiled, but it still starts in the same place). In your case, the first thing it does is include <string> into that file. Then it includes Person.h. Since <string> was already included, all the content of the string file is ahead of the person file in your code and everything is declared in the proper order. If you were to include Person.h before <string>, or not include <string> in your main file, you would indeed receive a compilation error.

#include directions act like copy/paste: it literally reads the <string> file and slaps its contents into the source file that it's included from. Next, the same thing is done to Person.h. So the end result after running the preprocessor is

<-- contents of <string> -->
<-- contents of Person.h -->

int main()
...

So in your example, everything is declared in the correct order.

ApproachingDarknessFish
  • 14,133
  • 7
  • 40
  • 79
  • To be a little more precise, compilation does not include ``, preprocessing does. – Chris Hayes Nov 03 '13 at 04:02
  • @ChrisHayes Yup. Fixed that. – ApproachingDarknessFish Nov 03 '13 at 04:03
  • Is it best-practice to #include the in the Person.h header file anyway? Or would it be bad to "duplicate" the code? Likewise, is it "bad" to #include in Person.cpp (it already is defined in main). In other words, why not just define everything in the file with the main function? I am a bit confused on when, where, and how many times we should use #include directives. –  Nov 03 '13 at 04:07
  • 2
    You might find the term 'translation unit' useful; it means the whole of the source code after the preprocessor has finished with it. The design of the `Person.h` header is defective; it is not self-contained and therefore is unnecessarily difficult to use. Headers should be self-contained (so that they can be used without requiring any other headers to be included beforehand) and idempotent (so they can be included twice, by design or — more usually — by accident) without breaking the compilation. Header guards provide idempotence; including `#include ` would provide self-containment. – Jonathan Leffler Nov 03 '13 at 04:07
  • 1
    @jakeliquorblues: See [Should I use `#include` in headers](http://stackoverflow.com/questions/1804486/). – Jonathan Leffler Nov 03 '13 at 04:08
  • @jakeliquorblues You normally don't need to worry about "duplicate code" due the usage of "include guards" (like in your Person.h file) that in effect prevent the contents of any file from being declared twice (even if the file is #include-ed multiple times). So yes, it's best to include you headers where you need them without relying on where the file is included from. – ApproachingDarknessFish Nov 03 '13 at 04:09