dlavila
dlavila

Reputation: 1212

Circular dependency with double dispatch

I'm trying to implement the double dispatch pattern but I get a circular dependency that I can't resolve with forward declaration (as it was resolved in this problem link).

Below is an example of my problem:

header 1:

class Object
{
    virtual void dispatchAdd(Collection& c) const = 0;
};

class Blockage: Object
{
    virtual void dispatchAdd(Collection& c) const
    {
       c.add(*this);
    }
};

class Boundary: Object
{
    virtual void dispatchAdd(Collection& c) const
    {
        c.add(*this);
    }
};

header 2:

class Collection
{
public:
    void add(const Blockage& b)
    { ... }

    void add(const Boundary& b)
    { ... }

   ...

private:
    boost::unordered_set<Boundary> m_boundaries;
    boost::unordered_set<Blockage> m_blockages;
}

I can't forward declare Boundary and Blockage in header 2, because I need a complete type to use boost::unordered_set. Any advice to resolve this problem?

Upvotes: 1

Views: 353

Answers (1)

Matthew Moss
Matthew Moss

Reputation: 1248

Forward declare Collection in header 1 and move the implementations for dispatchAdd out of the header file and into the source file.

objects.h (i.e. "header 1"):

class Collection;

class Object
{
    virtual void dispatchAdd(Collection& c) const = 0;
};

class Blockage: Object
{
    virtual void dispatchAdd(Collection& c) const;
};

class Boundary: Object
{
    virtual void dispatchAdd(Collection& c) const;
};

objects.cpp

#include "objects.h"     // i.e. "header 1"
#include "collection.h"  // i.e. "header 2"

void Blockage::dispatchAdd(Collection& c) const
{
    c.add(*this);
}

void Boundary::dispatchAdd(Collection& c) const
{
    c.add(*this);
}

Upvotes: 2

Related Questions