如何转发声明类模板



我正在尝试实现规范模式。其中,我有一个规范抽象类和一个重载的&返回AndSpecification的运算符,AndSpecification实际上是从Specification类派生的。现在我有一个循环依赖的问题,b/w AndSpecification和Specification。Specification是一个类模板,AndSpecification也是。

规格.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;
};

如有帮助,不胜感激。完整代码:https://github.com/princekm/specification.git

您需要前向声明,并将方法的定义移动到需要两个类定义的类之后:

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

演示

转发声明:

template <class T> AndSpecification;

以下是正确的(通过删除示例中的纯虚拟方法(:

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

您可以考虑Specification不一定需要知道AndSpecification,而不是转发声明(请参阅其他答案(。我的意思是,不管怎样,这是一个模板。如果您将模板模板参数添加到Specifiacation中,如下所示:

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

然后只有当你实例化它时,你才需要知道两者:

#include "Specification.h"
#incldue "AndSpecification.h"
template <typename T>
using Specification_with_And = Specification<T,AndSpecification>;

最新更新