В целях обучения на моих курсах по прикладным ориентированным объектам нас просят разработать полнофункциональное приложение C ++ без использования STL или каких-либо функций манипуляции со строками из cstring (SDL для GUI будет задействован на более позднем этапе).
Перерабатывая простые классы String и иерархии контейнеров списков, я столкнулся с проблемой циклической зависимости.Ранее я исправлял подобные проблемы, используя предварительную декларацию.Однако на этот раз все идет не так, как ожидалось, и эта проблема несколько дней занимала меня.
Вот простая UML-диаграмма проблемы, с которой я столкнулся.
![UML diagram](https://i.stack.imgur.com/0nVMV.png)
Каждый класс имеет свои собственные файлы .cpp
и .hpp
, за исключением BaseListItemNotFoundException
, который я объявляю с помощью оператора using
над объявлением класса BaseList
.
class BaseListItemNotFoundException: BaseException {
using BaseException::BaseException;
};
Даже если это не добавляет каких-либо добавленных фрагментов информации (IMHO), позвольте мне точно указать, BaseList
и HeplList
классы на самом деле являются шаблонными классами, определенными с использованием .ipp
и .hpp
.
Я опустил некоторые другие классы, задействованные для ограничения среды минимальным рабочим примером (иерархия универсальных классов итераторов и Cell используется в качестве полезной нагрузки для списков).Защита заголовка с использованием условий define
и ifndef
была удалена для ясности.
Вот отрывок файлов:
BaseList.hpp
:
#include <cstddef>
#include <iostream>
#include "Cell.hpp"
class HeplString; // Forward declaration
#include "BaseException.hpp"
class BaseListItemNotFoundException: BaseException {
using BaseException::BaseException;
};
template<class T>
class BaseList {
// code
};
HeplList.hpp
:
#include <cstddef>
#include "BaseList.hpp"
#include "Cell.hpp"
template<class T>
class HeplList : public BaseList<T> {
// code
};
#include "HeplList.ipp"
HeplString.hpp
:
#include <cstddef>
#include <iostream>
#include <ostream>
#include <fstream>
#include "HeplList.hpp"
class HeplString {
// code
};
BaseException.hpp
:
#include "HeplString.hpp"
#include "BaseList.hpp"
class BaseException {
// code
};
Основная проблема, с которой я сталкиваюсь в этом примере, - это ошибки типавот этот:
src/tests/../BaseException.hpp:9:20: error: field ‘msg’ has incomplete type ‘HeplString’
HeplString msg;
^~~
In file included from src/tests/../HeplList.hpp:5,
from src/tests/../HeplString.hpp:9,
from src/tests/test.cpp:2:
src/tests/../BaseList.hpp:9:7: note: forward declaration of ‘class HeplString’
class HeplString;
^~~~~~~~~~
Я не понимаю, что я делаю здесь неправильно.Чтение других подобных проблем не помогло.
Мой git-репозиторий с полным кодом доступен здесь, если необходимо: https://github.com/wget/hepl-2-cpp