0

我正在尝试学习 C++ 的基础。

在一本书中,有这样一段话:

例如,因为我们的 Sales_data 类有一个字符串成员,所以 Sales_data.h 必须#include 字符串头。正如我们所见,使用 Sales_data 的程序还需要包含字符串标题才能使用 bookNo(如果是 Sales_data 则为成员)

简短的问题:实际上我需要对此进行理论解释:如果我包含一个使用 std::string 的标头(因此它导入字符串),为什么我需要使用标头在主程序中再次导入?

长问题

我试图创建一个这样的演示程序:

销售数据.h

#include <string> 

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

程序2.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
    }

}

实际上,我在Linux下编译了它

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

但它不需要#include <string>在 prog2.cpp 代码中运行。

那么:是这本书有误,还是因为 g++ 运行良好而成为“案例”?

请注意,在本书的代码#include <string>中,prog2.cpp 文件中也有一个,所以我不明白它是更好还是强制性的,但没有它它也能正常工作!

*重要编辑*

这本书本身告诉我:

因此,使用 Sales_data 的程序将包含两次字符串标头:一次是直接包含,一次是包含 Sales_data.h 的副作用。因为一个标头可能被多次包含,我们需要以一种安全的方式编写我们的标头,即使标头被多次包含

4

3 回答 3

2

书没有错。虽然不是直接的,但您仍然<string>通过您的#include "Sales_data.h".

如果您需要完全定义的类型,那么是的,您需要完整的定义,通常在头文件中。

当您包含某些内容时,内容会有效地粘贴到您的翻译单元中。您可以将代码读取prog2.cpp为:

#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

    ///.............
    ///.............
    ///.............
于 2013-10-21T12:08:21.853 回答
1

如果我包含一个使用 std::string 的标头(因此它导入字符串),为什么我需要使用标头在主程序中再次导入?

你不必。如果您使用的是字符串,那么最好自己包含标题,而不是依赖其他标题为您包含它;但您不必这样做,只要包含它,代码就会编译。如果您不使用字符串,则无需包含它。

如果你的报价是准确的,这本书似乎告诉你必须,而不仅仅是你应该。这是错误的,但可能是鼓励良好习惯的合理简化。

于 2013-10-21T12:11:32.713 回答
0

我认为您在这里的困惑是您将“程序”表示为“我的包含 main() 的 cpp 文件”,而这本书的意思是“一起编译以创建最终可执行文件的所有源代码”

prog2.cpp包含Sales_data.hSales_data.h包含<string>所以<string>确实包含在程序中。

于 2013-10-21T12:11:08.560 回答