我在 Base.h :
中定义了基类Base
class Base
{ /* ... */ };
来自Child
的类模板Base
,在 Child.h 中定义:
#include "Base.h"
template <class T>
class Child : public Base
{ /* ... */ };
现在我想在Base
类中创建一些工厂方法,它应该将std::shared_ptr
返回到Child
类。为了避免循环依赖,我尝试使用前向声明。所以 Base.h 现在看起来像这样:
class Child; // new forward declaration
class Base
{
/* ... */
// new factory method
static std::shared_ptr<Base> CreateChildInt(int i = 0)
{
return std::make_shared<Child<int>>(i);
}
};
但是,CreateChildInt()
的定义会导致以下编译器错误:
“错误C2947:期待'&gt;'终止template-argument-list,找到'&lt;'“
这是否有可能实现我想要实现的目标? 如果没有,这种方法是否有任何变通方法/最佳实践?
修改:
我想将工厂方法放入Base
类而不是Child
的原因如下。当我将工厂放入Child
时,我需要像这样调用工厂方法:
std::shared_ptr<Base> p = Child<int>::CreateChildInt(3);
但是,我想在此调用中省略模板类型<int>
,因此:
std::shared_ptr<Base> p = Base::CreateChildInt(3);
答案 0 :(得分:3)
首先,您声明了一个类,但您定义的Child
实际上是一个模板。声明类模板的正确方法是:
template <class T>
class Child;
然而,单独一个正确的前瞻性声明对你没有帮助。 CreateChildInt::CreateChildInt
的实现必须知道Child
的完整定义,因为它创建了它的实例。你也不能在Child
之前定义Base
,因为继承也取决于完整的定义,所以你最终会得到一个cicrular依赖。
解决方案:转发声明Child
,然后定义Base
但不定义Base::CreateChildInt
内联,然后定义Child
,最后定义Base::CreateChildInt
。
PS。从OOP的角度来看,我发现基类成员函数的实现依赖于子类。我建议你考虑重新设计你的方法。