如何使用模板中的前向声明修复 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;
};

即使这没有添加任何附加信息(恕我直言),让我准确地说 BaseListHeplList classes 实际上是模板 classes使用 .ipp.hpp.

定义

我省略了一些其他的 classes 以将环境限制为最小的工作示例(迭代器和 Cell 通用 class 层次结构用作列表的有效负载)。 Header 使用 defineifndef 条件的保护已被删除,为清楚起见。

以下是文件的片段:

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 为他们做这件事。