Недавно я столкнулся с чем-то, что противоречит моему пониманию включений.
Я создаю dll для хранения базовых координатных объектов для личного игрового движка, который я разрабатываю (для забавы).
Основной заголовочный файл dll.
#pragma once
#include "sclapi.h"
#include "vector.h"
#include "point.h"
// Other includes and stuff.
// Unimportant for this demonstration.
sclapi.h
#pragma once
#ifdef SCL_EXPORTS
#define SCL_API __declspec(dllexport)
#else
#define SCL_API __declspec(dllimport)
#endif
vector.h
#pragma once
// No includes
/*EDIT*/struct Point;
struct SCL_API Vector {
float x, y;
// Other stuff
explicit operator Point() const;
};
point.h
#pragma once
// No includes
struct SCL_API Point {
int x, y;
// Other stuff
explicit operator Vector() const;
};
Мой код работает отлично;но, насколько я понимаю, это не должно быть.Заголовочный файл должен знать только то, что объявлено в нем (включая сокращение для вставки в код).Ни один из этих объектов не объявлен в заголовочных файлах другого.[EDITED] point.h не должен знать структуру Vector.Более того, оба даже знают макрос SCL_API.Если я закомментирую отдельные включения в основном заголовочном файле, я получу ожидаемые ошибки компилятора.Что мне не хватает?
РЕДАКТИРОВАТЬ:
После дальнейшего тестирования я обнаружил, что объявление более поздних объектов должно быть в первом заголовочном файле 'vector.h';но после этого их не нужно снова объявлять в любом другом заголовочном файле.Кроме того, объявление классов в главном заголовочном файле не работает.Объявление Point forward должно находиться внутри файла vector.h.