如何在共享指针中使用模板 class 的前向声明(在 C++ 中)
How to use forward declarations for a template class in a shared pointer (in C++)
我在 Base.h:
中定义了一个基数 class Base
class Base
{ /* ... */ };
以及从 Base
派生的 class 模板 Child
,在 Child.h:
中定义
#include "Base.h"
template <class T>
class Child : public Base
{ /* ... */ };
现在我想在 Base
class 中创建一些工厂方法,应该 return 一个 std::shared_ptr
到 Child
class.为了避免循环依赖,我尝试使用前向声明。所以 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()
的定义会导致以下编译器错误:
"error C2947: expecting '>' to terminate template-argument-list, found '<'"
那么这是否有可能实现我想要实现的目标?
如果没有,这种方法是否有任何解决方法/最佳实践?
编辑:
我之所以要将工厂方法放入Base
class 而不是Child
的原因如下。当我将工厂放入 Child
时,我需要像这样调用工厂方法:
std::shared_ptr<Base> p = Child<int>::CreateChildInt(3);
但是,我想在此调用中省略模板类型 <int>
,因此:
std::shared_ptr<Base> p = Base::CreateChildInt(3);
首先,你声明了一个class,但你定义的Child
实际上是一个模板。声明 class 模板的正确方法是:
template <class T>
class Child;
但是,仅靠正确的前向声明对您没有帮助。 CreateChildInt::CreateChildInt
的实现必须知道 Child
的完整定义,因为它创建了它的一个实例。你也不能在 Base
之前定义 Child
,因为继承也依赖于完整的定义,所以你最终会得到一个循环依赖。
解决方法:前向声明Child
,然后定义Base
但不要内联定义Base::CreateChildInt
,然后定义Child
,最后定义Base::CreateChildInt
。
PS。从 OOP 的角度来看,我发现基本 class 成员函数的实现取决于子 class 是可疑的。我建议您考虑重新设计您的方法。
我在 Base.h:
中定义了一个基数 classBase
class Base
{ /* ... */ };
以及从 Base
派生的 class 模板 Child
,在 Child.h:
#include "Base.h"
template <class T>
class Child : public Base
{ /* ... */ };
现在我想在 Base
class 中创建一些工厂方法,应该 return 一个 std::shared_ptr
到 Child
class.为了避免循环依赖,我尝试使用前向声明。所以 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()
的定义会导致以下编译器错误:
"error C2947: expecting '>' to terminate template-argument-list, found '<'"
那么这是否有可能实现我想要实现的目标?
如果没有,这种方法是否有任何解决方法/最佳实践?
编辑:
我之所以要将工厂方法放入Base
class 而不是Child
的原因如下。当我将工厂放入 Child
时,我需要像这样调用工厂方法:
std::shared_ptr<Base> p = Child<int>::CreateChildInt(3);
但是,我想在此调用中省略模板类型 <int>
,因此:
std::shared_ptr<Base> p = Base::CreateChildInt(3);
首先,你声明了一个class,但你定义的Child
实际上是一个模板。声明 class 模板的正确方法是:
template <class T>
class Child;
但是,仅靠正确的前向声明对您没有帮助。 CreateChildInt::CreateChildInt
的实现必须知道 Child
的完整定义,因为它创建了它的一个实例。你也不能在 Base
之前定义 Child
,因为继承也依赖于完整的定义,所以你最终会得到一个循环依赖。
解决方法:前向声明Child
,然后定义Base
但不要内联定义Base::CreateChildInt
,然后定义Child
,最后定义Base::CreateChildInt
。
PS。从 OOP 的角度来看,我发现基本 class 成员函数的实现取决于子 class 是可疑的。我建议您考虑重新设计您的方法。