如何使用模板中的前向声明修复 C++ 循环依赖 class header
How to fix a C++ cyclical dependency with forward declaration in template class header
为了在我面向应用的 object 课程中进行教学,我们被要求开发一个功能齐全的 C++ 应用程序,而不使用 STL 或来自 cstring 的任何字符串操作函数(稍后将涉及用于 GUI 的 SDL舞台)。
在重新开发简单的字符串和列表容器层次结构 classes 时,我遇到了循环依赖性问题。以前,我使用前向声明解决了这类问题。然而,这一次,事情并没有像预期的那样进行,这个问题让我忙了几个晚上。
这是我遇到的问题的简单 UML 图。
每个 class 都有自己的 .cpp
和 .hpp
文件,除了 BaseListItemNotFoundException
我在 [=22= 上面用 using
语句声明] class声明。
class BaseListItemNotFoundException: BaseException {
using BaseException::BaseException;
};
即使这没有添加任何附加信息(恕我直言),让我准确地说 BaseList
和 HeplList
classes 实际上是模板 classes使用 .ipp
和 .hpp
.
定义
我省略了一些其他的 classes 以将环境限制为最小的工作示例(迭代器和 Cell 通用 class 层次结构用作列表的有效负载)。 Header 使用 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
- 将
#include "BaseException.hpp"
添加到 BaseList.hpp
- 将
#include "HeplList.hpp"
添加到HeplString.cpp
- 将前向声明
template<class T> class HeplList;
添加到HeplString.hpp
- 现在,您可能需要修改不包括
BaseList.hpp
header 的其他一些 类,因为它们依赖于 header HeplString.hpp
为他们做这件事。
为了在我面向应用的 object 课程中进行教学,我们被要求开发一个功能齐全的 C++ 应用程序,而不使用 STL 或来自 cstring 的任何字符串操作函数(稍后将涉及用于 GUI 的 SDL舞台)。
在重新开发简单的字符串和列表容器层次结构 classes 时,我遇到了循环依赖性问题。以前,我使用前向声明解决了这类问题。然而,这一次,事情并没有像预期的那样进行,这个问题让我忙了几个晚上。
这是我遇到的问题的简单 UML 图。
每个 class 都有自己的 .cpp
和 .hpp
文件,除了 BaseListItemNotFoundException
我在 [=22= 上面用 using
语句声明] class声明。
class BaseListItemNotFoundException: BaseException {
using BaseException::BaseException;
};
即使这没有添加任何附加信息(恕我直言),让我准确地说 BaseList
和 HeplList
classes 实际上是模板 classes使用 .ipp
和 .hpp
.
我省略了一些其他的 classes 以将环境限制为最小的工作示例(迭代器和 Cell 通用 class 层次结构用作列表的有效负载)。 Header 使用 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
- 将
#include "BaseException.hpp"
添加到BaseList.hpp
- 将
#include "HeplList.hpp"
添加到HeplString.cpp
- 将前向声明
template<class T> class HeplList;
添加到HeplString.hpp
- 现在,您可能需要修改不包括
BaseList.hpp
header 的其他一些 类,因为它们依赖于 headerHeplString.hpp
为他们做这件事。