2

Why do we need to include headers (like string, iostream) into a header containing the class definition (class requires I/O or string proration) - as the headers are already included into the cpp translational unit where this class header is included.

It seems like doubling the content. Isn't the header material first pasted into the the cpp file where it has been included?

example:

 //HEADER
 #ifndef SAMPLE_H
 #define SAMPLE_H

 class sample
 {
      public:
      sample();
 }

 sample::sample()
 {
     cout<<"Constructor!!!\n";     //error
 }

 #endif


//CPP
#include<iostream>
#include"m.h"

using namespace std;

int main()
{
    m obj();
    return 0;
}

The error thrown is:

error: ‘cout’ was not declared in this scope

Even when i have used using namespace std in the cpp file. So either I have to include iostream in the class definition file or use std before using cout - But why? Since the iostream and namespace has already been included into the main translational unit.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Gaurav
  • 1,570
  • 5
  • 17

3 Answers3

2

For starters pay attention to that there is a typo in the class definition. You forgit to place a semicolon after the class definition

class sample
{
      public:
      sample();
};
^^^ 

A name used in some context shall be already declared before its usage.

So if a class definition references for example the standard class std::string then the header <string> should be included.

Take into account that the header can be used by other users or compilation units that do not know that they need to include the header <string> before using the header with the class definition.

In your example of a header you have to include the header <iostream> and either to use the qualified name std::cout or use a using declaration for std::cout or using directive for the namespace std.

Otherwise this header can be a source of errors because users of the header can forget to include the header <iostream> in their programs before including your header.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

You don't have to include the other headers; you could have a file structure that only put the necessary #include directives in the source files. But that gets really annoying, really fast.

// myheader.h
#ifndef MYHEADER_H
#define MYHEADER_H
struct S { std::string data; };
#endif MYHEADER_H

// test.cpp
#include <string>
#include "myheader.h"
S s; // ok

but if you leave out that #include directive you get an error:

// test.cpp
#include "myheader.h" // error: std::string undefined

The usual convention is to write headers that can compile on their own:

// myheader.h
#ifndef MYHEADER_H
#define MYHEADER_H
#include <string>
struct S { std::string data; };
#endif MYHEADER_H

with this header, both versions of test.cpp will compile.

This doesn't double the content. Headers are written so that you can #include them as many times as you like without duplicating their contents. That's what that #ifndef stuff is for. If the header has already been included the preprocessor will see the definition of the guard variable (MYHEADER_H in this case) and skip the contents of the file the second and subsequent times around. So you can write this:

// test1.cpp
#include "myheader.h"
#include "myheader.h"

and only get the contents of myheader.h once. In fact, if you leave out the include guards you'll get an error if you try to include the same header more than once in the same cpp file.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
1

What you may overlook is that m.h is included not only in test.cpp, but possibly also in many other files that need class sample. If you don't include <iostream> inside m.h, you force every other file to include <iostream> before m.h.

With bigger projects, your strategy can make it very difficult to get the header order right. In what order should A.h through D.h be included in E.cpp? How would the author of E.cpp know?

There's one workable exception to this rule. You can realistically have a project-wide meta-header that's always included first, and which in turn includes a few common headers such as <string> and <vector>. If you use this strategy, those headers do not need to be included inside your own .h files. This approach is especially common with Visual C++, where such a header is commonly named stdafx.h.

MSalters
  • 173,980
  • 10
  • 155
  • 350