Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
a.h: // интерфейс
#include // в интерфейсе будет вектор. Инклюдим.
class A
{
public:
virtual ~A(){};
virtual std::vector getVector() = 0;
}
b.h: // реализация
#include "a.h"
#include // используем вектор? Опять инклюдим.
class B : public A
{
public:
virtual ~B(){};
virtual std::vector getVector()
{
// реализация
return m_Data;
};
private:
std::vector m_Data;
}
c.h:
// нет инклюда вектора! Забыли включить, например. (1)
struct C
{
std::vector arr; // (2) см ниже.
}
use1.cpp: // Ваш вариант.
#include // СТЛ в начале
#include "c.h" // (2) не ругается
#include "a.h"
use2.cpp: // тут самое интересное
#include "c.h" // (3) ругается
#include "a.h"
#include // СТЛ в конце
use3.cpp
#include "a.h"
#include "c.h" // (4) не ругается ни в каком случае.
}
Может, я чего-то не понимаю в этой жизни, но при моем варианте я при ошибке в use2.cpp в месте (3) полезу в (1) и вставлю недостающий инклюд. В Вашем случае (use1.cpp) ошибки сборки не будет и файл c.h, вероятно, так и останется с недочетом.
Более того, если поменять включение "a.h" и "c.h" местами (как это сделано в use3.cpp) - то всё будет собираться. И ломать голову, почему в (4) всё собирается, а в (2) - нет - ну хотя бы лишняя потеря времени.
Самодостаточность файлов это включает в себя независимый порядок их включения, разве не так?
Тонкости реализации кода библиотеки. Часть вторая