Почему при импорте файла заголовка класса «A» в исходный файл класса «B» содержимое класса «A» определяется внутри файла заголовка класса «B»? - PullRequest
0 голосов
/ 28 апреля 2020

Предположим, у меня есть класс с именем Class:

Class.h:

#pragma once

class Class
{
public:

    std::vector<int> x();
};

Class.cpp:

#include <vector>
#include "Class.h"

std::vector<int> Class::x()
{
    return std::vector<int>();
}

Полагаю, что этот код не должен компилироваться, так как std::vector не определен в Class.h. Но код работает. Это не сработает, если я включу необходимые заголовки (в данном случае это просто vector) после включения Class.h. Но пока необходимые заголовки импортируются до включения Class.h, все работает нормально. Также это не работает, если я пытаюсь включить Class.h где-то в одиночку и пытаюсь использовать его. Так, например, этот код не будет работать:

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

    int main()
    {
        Class c;
        auto x = c.x();

        x.push_back(1);
        x.push_back(2);
        x.push_back(3);

        for (auto i : x)
            std::cout << i << ' ';
    }

Но если я включу необходимые заголовки, он работает нормально. Так что в этом примере это работает, если я включаю заголовок vector (также должен быть перед включением Class.h):

#include <vector>
#include "Class.h"
#include <iostream>

int main()
{
    Class c;
    auto x = c.x();

    x.push_back(1);
    x.push_back(2);
    x.push_back(3);

    for (auto i : x)
        std::cout << i << ' ';
}

Я думаю о #include как о просто наклеивать. В Class.h заголовок не включается. Как можно сказать, что эта функция вернет std::vector без определения? И почему включение заголовков в исходный файл делает его таким, как если бы он был включен в заголовочный файл?

1 Ответ

1 голос
/ 28 апреля 2020

Вы не компилируете Class.h, вы компилируете файл cpp, который #include s Class.h.

Если вы включите векторный заголовок перед Class.h в main.cpp, тогда после шага препроцессора ваш файл main.cpp будет иметь содержимое заголовка vector, затем содержимое Class.h, а затем другой код в main.cpp. Таким образом, определение vector будет видно в Class.

Если вы скомпилируете только заголовок Class.h отдельно, вы получите ошибку. Я советую вам всегда делать это, чтобы проверить, имеют ли ваши заголовочные файлы все необходимые заголовки и могут ли они компилироваться, не полагаясь на побочные эффекты.

...