推荐的 C++ 包含实践

Recommended C++ Include Practice

在以下情况下,包含 <string> header 的最佳方法是什么?

main.cpp

#include "extra.h"

int main() {
    func("A string");
    return 0;
}

extra.h

#ifndef EXTRA_H
#define EXTRA_H

    #include <string>

    void func(std::string);

#endif

extra.cpp

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

void func(std::string str) {
    std::cout << str << '\n';
}

头文件应尽可能少包含。这样可以保持干净,还可以加快编译速度。如果头文件需要一个完整的类型,您必须在头文件中包含该类型的包含文件,否则使用前向声明。

例如main.h

#pragma once

// if your header uses a full type (see function h)
// it needs to know the size of the type
// then include header file for that type in your header

#include <string>
void h(std::string str);

// if your header only has references or pointers to a type
// then add a forward declaration of that type.
// The compiler only has to know the size for the reference/pointer

struct struct_t; 

void f(const struct_t& s);
void g(const struct_t* s);

然后main.cpp

#include "main.h"
#include <iostream>
// #include <string> not really needed already done in "main.h"

// full declaration of struct_t in the place where it is needed.
// note this could also be in done in its own header file. 
struct struct_t
{
    int value1;
    int value2;
};

void f(const struct_t& s)
{
    std::cout << s.value1 << std::endl;
    std::cout << s.value2 << std::endl;
}

void g(const struct_t* s)
{
    std::cout << s->value1 << std::endl;
    std::cout << s->value2 << std::endl;
}

void h(std::string s)
{
    std::cout << s << std::endl;
}

int main()
{
    struct_t values{ 0, 42 };
    f(values);
    g(&values);
    h("Hello World!");
}

您的 extra.h 包括 <string> 因为它直接使用它。在您的 main.cpp 中没有直接使用 std::string,因此在其中包含 <string> 会很奇怪。

此外,在 extra.cpp 中包含 <string> 是完全没有必要的,因为 std::string 的使用是在函数签名中,您知道它在 extra.h 中声明,加上两个 extra 文件的维护可以合理地预期作为单个操作完成,所以不用担心 extra.h 突然不包括 <string> 然后破坏 extra.cpp,因为他们会一起维护。