Reputation: 323
I'm trying to implement the specification pattern.In that, I have a specification abstract class and an overloaded && operator which returns AndSpecification, which is actually derived from Specification class.Now I have the problem of circular dependency b/w AndSpecification and Specification.Specification is a class template so is AndSpecification.
Specification.h
//#include "AndSpecification.h"- this creates a problem
template <class T>
class Specification
{
public:
Specification()
{
}
virtual ~Specification()
{
}
virtual bool isSatisfied(T *item)=0;
AndSpecification<T> operator&&(Specification &other)
{
return AndSpecification<T>(*this,other);
}
};
AndSpecification.h
#include "Specification.h"
template <class T>
class AndSpecification : public Specification<T>
{
Specification <T> *first;
Specification <T> *second;
public:
AndSpecification(Specification <T> *first,Specification <T> * second);
// Specification interface
public:
bool isSatisfied(T *item) override;
};
A help would be appreciated. full code:https://github.com/princekm/specification.git
Upvotes: 0
Views: 194
Reputation: 122458
Instead of forward declaration (see other answers) you can consider that Specification
does not necessarily need to know about AndSpecification
. I mean, its a template anyhow. If you add a template template parameter to Specifiacation
like this:
template <class T,template<typename> class X>
class Specification
{
public:
Specification()
{
}
virtual ~Specification()
{
}
virtual bool isSatisfied(T *item)=0;
X<T> operator&&(Specification &other)
{
return X<T>(*this,other);
}
};
Then only when you instantiate it you need to know both:
#include "Specification.h"
#incldue "AndSpecification.h"
template <typename T>
using Specification_with_And = Specification<T,AndSpecification>;
Upvotes: 0
Reputation: 217275
You need forward declaration, and move definition of your method which need both class definition after those classes:
// Specification.h
#pragma once
template <class T> class AndSpecification;
template <class T>
class Specification
{
public:
Specification() {}
virtual ~Specification() {}
virtual bool isSatisfied(T *item)=0;
AndSpecification<T> operator&&(Specification &other);
};
#include "Specification.inl"
// AndSpecification.h
#pragma once
#include "Specification.h"
template <class T>
class AndSpecification : public Specification<T>
{
Specification <T> *first;
Specification <T> *second;
public:
AndSpecification(Specification <T> *first,Specification <T> * second);
// Specification interface
public:
bool isSatisfied(T *item) override;
};
// Specification.inl
#pragma once
#include "Specification.h"
#include "AndSpecification.h"
template <class T>
AndSpecification<T> Specification<T>::operator&&(Specification &other)
{
return AndSpecification<T>(this, &other);
}
Upvotes: 1
Reputation: 36401
Forward declare it:
template <class T> AndSpecification;
The following is correct (by removing the pure virtual method for the example):
template <class T> class AndSpecification;
template <class T>
class Specification
{
public:
Specification()
{
}
virtual ~Specification()
{
}
// virtual bool isSatisfied(T *item)=0;
AndSpecification<T> operator&&(Specification &other)
{
return AndSpecification<T>(*this,other);
}
};
template <class T>
class AndSpecification : public Specification<T>
{
Specification <T> *first;
Specification <T> *second;
public:
AndSpecification(Specification <T> *first,Specification <T> * second);
// Specification interface
public:
bool isSatisfied(T *item) override;
};
class A{};
int main() {
Specification<A> a;
}
Upvotes: 0