wget
wget

Reputation: 195

How to fix a C++ cyclical dependency with forward declaration in template class header

For teaching purposes in my applied oriented object courses, we are asked to develop a fully featured C++ application without using the STL nor any string manipulation functions from cstring (SDL for GUI will be involved in a later stage).

While redeveloping simple String and list container hierarchy classes, I encountered a cyclical dependency issue. Previously, I fixed these kind of issues using forward declaration. However, this time, things do not go as expected and this problem kept me busy for a few evenings now.

Here is a simple UML diagram of the issue I have.

UML diagram

Every class has their own .cpp and .hpp files, except for BaseListItemNotFoundException I declare with a using statement above the BaseList class declaration.

class BaseListItemNotFoundException: BaseException {
    using BaseException::BaseException;
};

Even if this doesn't add any added pieces of info (IMHO), let me precise BaseList and HeplList classes are actually template classes defined using .ipp and .hpp.

I omitted some other classes involved to restrict the environment to a minimal working example (iterator and Cell generic class hierarchy used as payload for the lists). Header protections using define and ifndef conditions have been removed for clarity.

Here are a snipped of the files:

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
};

The main issue I have with this example is errors like this one:

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;
       ^~~~~~~~~~

I don't understand what I'm doing wrong here. Reading other similar issues didn't help.

My git repository with the full code is available here, if needed: https://github.com/wget/hepl-2-cpp

Upvotes: 0

Views: 552

Answers (1)

wget
wget

Reputation: 195

  • Add #include "BaseException.hpp" to BaseList.hpp
  • Add #include "HeplList.hpp" to HeplString.cpp
  • Add the forward declaration template<class T> class HeplList; to HeplString.hpp
  • Now, you may need to modify some of your other classes which weren't including the BaseList.hpp header because they were relying on the header HeplString.hpp to do this for them.

Upvotes: 1

Related Questions