0

I'm trying to learn the bases of c++.

In a book, there is this:

For example, because our Sales_data class has a string member, Sales_data.h must #include the string header. As we’ve seen, programs that use Sales_data also need to include the string header in order to use the bookNo (member if Sales_data)

Short question: Actually I need a theoric explanation of this: if I include an header which is using std::string (so it imports string), why I need to import again in the main program using the header ?

Long question

I tried to create a demo program like this:

Sales_data.h

#include <string> 

struct Sales_data {
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};

prog2.cpp

#include <iostream>
#include "Sales_data.h"

int main()
{
    Sales_data data1, data2;
    double price = 0;  // price per book, used to calculate total revenue

    std::cin >> data1.bookNo >> data1.units_sold >> price;
    data1.revenue = data1.units_sold * price;

    std::cin >> data2.bookNo >> data2.units_sold >> price;
    data2.revenue = data2.units_sold * price;

    if (data1.bookNo == data2.bookNo) {
        unsigned totalCnt = data1.units_sold + data2.units_sold;
        double totalRevenue = data1.revenue + data2.revenue;

        std::cout << data1.bookNo << " " << totalCnt 
                  << " " << totalRevenue << " ";
        if (totalCnt != 0)
            std::cout << totalRevenue/totalCnt << std::endl;
        else
            std::cout  << "(no sales)" << std::endl;

        return 0;  // indicate success
    } else {
        std::cerr << "Data must refer to the same ISBN" 
                  << std::endl;
        return -1; // indicate failure
    }

}

Actually, I compiled it, under Linux with

g++ prog2.cpp -o prog2 -std=c++11

But it runs without need to #include <string> in the prog2.cpp code.

So: is it the book in error, or it's a 'case' because g++ work well anyway ?

Please note that in book's code there is a #include <string> also in prog2.cpp file, so I cannot understand if it's better or it's mandatory, but it works fine without it !

*Important edit *

The book itself is telling me this:

As a result, programs that use Sales_data will include the string header twice: once directly and once as a side effect of including Sales_data.h. Because a header might be included more than once, we need to write our headers in a way that is safe even if the header is included multiple times

3 Answers 3

2

The book isn't wrong. Although not directly, you are still including <string> through your #include "Sales_data.h".

If you need a completely defined type, then yes, you need the full definition, which is usually in a header file.

When you include something, the contents is effectively pasted into your translation unit. You could read your code in prog2.cpp as:

#include <iostream>

#include <string> 

struct Sales_data {
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};

int main()
{
    Sales_data data1, data2;
    double price = 0;  // price per book, used to calculate total revenue

    ///.............
    ///.............
    ///.............
Sign up to request clarification or add additional context in comments.

8 Comments

I still don't understand why this works without #include <string> in prog2 code if it is needed.
@realtebo the include is there, in Sales_data.h, which you included.
So, have I misunderstood what the book is telling me ? I think that ```programs that use Sales_data also need to include the string header`` mean that Sales_data need the import AND the code which used Saled_data ALSO NEEDS import string header; so I've understood I need 2 times the string header
@realtebo the book itself TELLS TO DO IT TWICE no it doesn't. If it does, it's wrong. You can, but don't have to.
@realtebo it's not mandatory, yes, but recommended in case you remove the include from the header.
|
1

if I include an header which is using std::string (so it imports string), why I need to import again in the main program using the header ?

You don't have to. If you are using strings, then it's a good idea to include the header yourself rather than relying on other headers to include it for you; but you don't have to, and the code will compile as long as something includes it. If you're not using strings, then there's no need to include it.

If your quotes are accurate, the book appears to be telling you that you must, rather than just that you should. That's wrong, but probably a justifiable simplification to encourage good habits.

1 Comment

``` If you are using strings, then it's a good idea to include the header yourself rather than relying on other headers to include it for you.```, ok this is a good answer ! It's a good idea, it's not mandatory !
0

I think your confusion here is that you're taking "the program" to mean "my cpp file containing main()" whereas the book means "all the source that is compiled together to create the final executable"

prog2.cpp includes Sales_data.h and Sales_data.h includes <string> so <string> is indeed included in the program.

4 Comments

So, have I misunderstood what the book is telling me ? I think that ```programs that use Sales_data also need to include the string header`` mean that Sales_data need the import AND the code which used Saled_data ALSO NEEDS import string header
Yes, exactly. If you remove the string include from Sales_data.h you'll find that your code no longer compiles, as the compiler won't know what std::string is. You could put the string include at the top of prog2.cpp and it would work again. Basically, when you use a #include the compiler just copy/pastes the contents of those files into your source, so you need to make sure string is includes somewhere before std::string is used
Aha, I understand your confusion now - yes, in this case you are quite right, this particular cpp file doesn't need to include string again, as it's already included. I presume the book is talking about header guards? In this case it may not be the best example, but when you start having multiple cpp files including the same files, you'll see the kind of multiple definition problem it's talking about
Yes, I understand the multiple header problem. Probably I understand the main problem: if I use std::string in progr2.cpp than I really need to include 'twice' the string header. If is it the problem, I'm feeling stupid ... Please update your question to reflect last comment. !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.