-1

I have a header file, called Person.h:

class Person
{
    public:
        Person();
    private:
        std::string name;
};

The implementation is in the file called Person.cpp:

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

Person::Person()
{
    name = "foo";
}

I'm used to avoid nested include files so I'm #include-ing the <string> header before including the class header in the class source file.

Now this doesn't compile with the error that std::string is not a defined name. But if I include in the header file it compiles.

On the web I found that including headers, paying attention to the order of inclusion (which is what I regularly do in C, my primary language) indeed should work (include files are not compiled by themselves but just inserted in the source file).

So my question is, why doesn't it compile without including the string header in the header file? Because the header file is "copy-pasted" into the source file after #include <string>, I expect it to compile just fine.

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
Luca
  • 1,658
  • 4
  • 20
  • 41
  • OK, let's examine your basic assumptions. Why is it specifically that you're "*used to avoid[ing] nested include files*" (which I take to mean including headers from other headers)? – NPE Dec 29 '16 at 18:49
  • @NPE please, answer my question. as I wrote, it works in C, I want to know why it shouldn't in C++, even if I found on the web that it should – Luca Dec 29 '16 at 18:51
  • 3
    If you are including the header in other source files, you may not be remembering to include string in the correct location in those files. Which ends up being the primary reason to include all files needed for a header file in that header file. – Mikel F Dec 29 '16 at 18:54
  • @MikelF I know that. I want to know why (even if it's not the best practice) it doesn't work even if it should – Luca Dec 29 '16 at 19:01
  • one problem is that in C, if you want to declare a string in your header file, person.h, you'd just say `char *foo;` since the `char` type is part of the language definition. But in C++, you have to include the `` header to get the `std::string` type defined. – bruceg Dec 29 '16 at 19:02
  • 2
    @Luca There is nothing in the code that you have shared that should be causing a problem, which suggests that the issue exists in some other part of your code. – Mikel F Dec 29 '16 at 19:06
  • @MikelF I was including the header in main. Hence the error. Thanks, you and another user answered my question. If you turn the comment into an answer I can flag it as correct and close – Luca Dec 29 '16 at 19:08
  • 1) use header guards (to guard against multiple/recursive definitions and to make include order irrelevant). 2) in implementation files; always include own header first (so you know it is self contained). Unfortunately, in your example, you do neither :-( – Jesper Juhl Dec 29 '16 at 19:36

3 Answers3

3

The problem is that the header must include the headers for type definitions on which it relies, or forward-declare types for which it needs only a pointer a reference.

Move the inclusion of <string.h> to your header file to fix this problem.

You do not need to worry about multiple inclusions, because all standard headers use Inclusion Guards. You need to add inclusion guards to your own headers as well.

[needing to see forward declarations is] the same in C. But it should get them from the header file included before in the cpp file.

It appears that there are other places from which you include Person.h header file, in addition to Person.cpp. This is what triggers the error.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • yes,I know that it needs to see forward declarations. It's the same in C. But it should get them from the header file included before in the cpp file. – Luca Dec 29 '16 at 18:52
  • 3
    @Luca It appears that there are other places from which you include `Person.h` header (assuming that you are not passing the header to the compiler as one of the translation unit, because that would be a mistake). – Sergey Kalinichenko Dec 29 '16 at 18:57
  • thanks! yours is the only pertinent answer to my question. It is indeed so, I was including the header in main.cpp as well, hence the error. So it was just a stupid error of mine, inclusion works the same as in C. If you make this comment an answer I can flag it as correct. Thanks – Luca Dec 29 '16 at 19:07
1

It is best to include all relevant headers for your class in the header file for that class. Choosing not to do so then requires that you remember to include the necessary headers in every other file that uses your class, and as you add new functionality to your class, and hence the need for additional headers, you then have to visit every place where your class header has been included and add the proper headers to each file.

Mikel F
  • 3,567
  • 1
  • 21
  • 33
0

You want to use, as standard header files and everyone else do, include guards

#ifndef PERSON_H
#define PERSON_H

/// your header file

#endif // PERSON_H
Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • I know that. It's just a simple example. Library headers indeed have header guards. But why it doesn't work? – Luca Dec 29 '16 at 18:53