为什么省略“一”字#包括<;字符串>&引用;只是有时会导致编译失败? 我是一个C++初学者。当我写代码时,有时我写#include代码就行了,有时我不写#include代码就不行了。但有时它在没有#include的情况下工作

为什么省略“一”字#包括<;字符串>&引用;只是有时会导致编译失败? 我是一个C++初学者。当我写代码时,有时我写#include代码就行了,有时我不写#include代码就不行了。但有时它在没有#include的情况下工作,c++,string,include,C++,String,Include,那么我是否必须编写#include,这样代码才能工作 如果使用在标准头字符串中声明的成员,则必须直接或间接(通过其他头)包含该头 某些平台上的某些编译器可能会在一个月的某个时间编译,即使您没有包含头。这种行为是不幸的、不可靠的,并不意味着不应该包含标题 原因很简单,因为您包含了其他标准标题,这些标题也碰巧包含string。但正如我所说的,这通常是不可靠的,而且可能会发生非常突然的变化(例如,当安装了新版本的编译器时) 始终包括所有必要的标题。不幸的是,似乎没有可靠的在线文档需要包含标题。查阅一本

那么我是否必须编写
#include
,这样代码才能工作

如果使用在标准头
字符串
中声明的成员,则必须直接或间接(通过其他头)包含该头

某些平台上的某些编译器可能会在一个月的某个时间编译,即使您没有包含头。这种行为是不幸的、不可靠的,并不意味着不应该包含标题

原因很简单,因为您包含了其他标准标题,这些标题也碰巧包含
string
。但正如我所说的,这通常是不可靠的,而且可能会发生非常突然的变化(例如,当安装了新版本的编译器时)

始终包括所有必要的标题。不幸的是,似乎没有可靠的在线文档需要包含标题。查阅一本书,或者官方C++标准。< /P> 例如,以下代码使用我的编译器编译(
gcc
4.6):

#包括
int main(){
std::字符串str;
}

但是如果我删除第一行,它将不再编译,即使
iostream
头实际上应该是不相关的。

如果您使用在标准头
string
中声明的成员,那么是的,您必须直接或间接地(通过其他头)包含该头

某些平台上的某些编译器可能会在一个月的某个时间编译,即使您没有包含头。这种行为是不幸的、不可靠的,并不意味着不应该包含标题

原因很简单,因为您包含了其他标准标题,这些标题也碰巧包含
string
。但正如我所说的,这通常是不可靠的,而且可能会发生非常突然的变化(例如,当安装了新版本的编译器时)

始终包括所有必要的标题。不幸的是,似乎没有可靠的在线文档需要包含标题。查阅一本书,或者官方C++标准。< /P> 例如,以下代码使用我的编译器编译(
gcc
4.6):

#包括
int main(){
std::字符串str;
}

但是,如果删除第一行,它将不再编译,即使
iostream
头实际上应该是不相关的。

如果您只是使用指向用户定义类型的指针/引用,则只需要声明该类型:

class my_class;
void foo(const my_class& c);
但是当您使用该值时,编译器需要知道大小以及类型的定义


请记住,标准标头可能包括其他标头,这并不意味着所有实现都会这样做,因此您不能依赖于此。

如果您只是使用指向用户定义类型的指针/引用,则只需声明该类型:

class my_class;
void foo(const my_class& c);
但是当您使用该值时,编译器需要知道大小以及类型的定义

请记住,标准头可能包括其他头,这并不意味着所有实现都会这样做,因此您不能依赖于此。

您所包含的其他头可能包含

尽管如此,通常最好将
#直接包含在您的代码中,即使对于成功构建来说并非绝对必要,以防这些“其他”标题发生更改-例如,由于不同(或不同版本)的编译器/标准库实现、平台,甚至只是构建配置

(当然,本讨论适用于任何标题,而不仅仅是

您所包含的其他标题也可能包含

尽管如此,通常最好将
#直接包含在您的代码中,即使对于成功构建来说并非绝对必要,以防这些“其他”标题发生更改-例如,由于不同(或不同版本)的编译器/标准库实现、平台,甚至只是构建配置

(当然,此讨论适用于任何头文件,而不仅仅是

尽管在特定源文件中没有直接出现
#include
,但并不意味着它没有被其他头文件包含。考虑这一点:

文件:
header.h

#if !defined(__HEADER_H__)
#define __HEADER_H__

// more here
#include <string>
// ...and here

#endif
文件:
source2.cc

#include <string>

void foo()
{
    // No error here.
    string s = "Foo";
}
#include <header.h>

void bar()
{
    // Still no error, since there's a #include <string> in header.h
    string s = "Bar";
}
void zoid()
{
    // Here's the error; no such thing as "string", since non of the
    // previous headers had been included.
    string s = "Zoid";
}
尽管在特定的源文件中没有直接出现
#include
,但这并不意味着它没有被另一个头文件包含。考虑这一点:

文件:
header.h

#if !defined(__HEADER_H__)
#define __HEADER_H__

// more here
#include <string>
// ...and here

#endif
文件:
source2.cc

#include <string>

void foo()
{
    // No error here.
    string s = "Foo";
}
#include <header.h>

void bar()
{
    // Still no error, since there's a #include <string> in header.h
    string s = "Bar";
}
void zoid()
{
    // Here's the error; no such thing as "string", since non of the
    // previous headers had been included.
    string s = "Zoid";
}

标题字符串不是由其他标题包含的。标题字符串本身只有includes。没有定义。因此,使用字符串所需的所有必要定义都包含在标题字符串包含的标题中。这些标题可能已经包含在其他标题中。然后一切都开始了。例如,头ios包括stringbuf,其中包括…

头字符串不包括在其他头中。标题字符串本身只有includes。没有定义。因此,使用字符串所需的所有必要定义都包含在标题字符串包含的标题中。这些标题可能已经包含在其他标题中。然后一切都开始了。例如,头ios包括stringbuf,其中包括…

,即使您没有明确地包括字符串,但由于另一个标准头yo,它也被包括在内