В следующем сценарии, как лучше всего включить заголовок <string>?

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';
}

0
Locklan 18 Сен 2021 в 07:52

2 ответа

Лучший ответ

Ваш extra.h включает <string>, потому что использует его напрямую. В вашем main.cpp нет прямого использования std::string, поэтому было бы странно включать туда <string>.

Кроме того, включение <string> в extra.cpp совершенно не нужно, потому что использование std::string находится в сигнатуре функции, которая, как вы знаете, объявлена ​​в extra.h, плюс поддержание двух Разумно ожидать, что файлы extra будут выполняться как одна операция, поэтому не стоит беспокоиться о том, что extra.h внезапно не включит <string>, а затем сломает extra.cpp, потому что они будут поддерживаться вместе.

3
John Zwinck 18 Сен 2021 в 05:58

Заголовочный файл должен содержать как можно меньше включений. Это сохраняет его чистоту, а также позволяет ускорить компиляцию. Если заголовочный файл нуждается в полном типе, вы должны включить включаемый файл для этого типа в свой заголовочный файл, иначе используйте форвардные объявления.

Например, 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!");
}
1
P Kramer 18 Сен 2021 в 06:29