lundi 31 juillet 2023

C++ Problem with handling a state between two classes in a hierarchy

Problem Description

Consider the following class hierarchy. Concrete templated class A, templated abstract class B and an interface C, with A <-- B <-- C. Consider that B has a function declaration

virtual std::optional<T> foo() const  = 0;

and c has a function declaration

virtual bar() = 0;

both of which are defined in A appropriately.

There exists somewhere in the code a list of objects B, over which we call foo(), and there exists a list of C* pointers over which we call bar().

For a minimal example:

Example and My Issue

class A <typename T> : public B <T>
{
public: 
    std::optional<T> foo() const override { /*...*/ };
    bar() override { /*...*/ };

    // ...
};

class B <typename T> : public C
{
public: 
    virtual std::optional<T> foo() const = 0;

    // ...
}

class C
{
public: 
    virtual bar() = 0;
}

The issue I am having is that I want to add a boolean state over this small hierarchy. Particularly, I have the following requirements

  1. I need a boolean state m_isInteresting over the object represented by this hierarchy.
  2. I don't want m_isInteresting state it to be in A (for decoupling reasons).
  3. I want foo() to set m_isInteresting = true;.
  4. I want bar() to set m_isInteresting = false;.

How can I achieve this?

Things I have tried

  • I tried to create a decorator wrapper around C with the m_isInteresting member and the appropriate accessors, with a method forward of bar(), in which I call C's bar() function and set the class member m_isInteresting to false, but then I can't set the member to true because foo() is down the class hierarchy.
  • I tried to move foo()'s declaration to C (while keeping it's definition in A), but this is very difficult because the function returns a std::optional<T> and well, C is not templated; a derived class's function signature must match that of the base class.
  • I have thought of making decorator classes for both B and C with m_isInteresting shared between them, but held externally, but this is getting ugly and complicated.

There must be something that I am missing here.

Aucun commentaire:

Enregistrer un commentaire