如何在共享指针中使用模板 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_ptrChild 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 是可疑的。我建议您考虑重新设计您的方法。