简体   繁体   English

如何在共享指针中对模板类使用前向声明(在C ++中)

[英]How to use forward declarations for a template class in a shared pointer (in C++)

I have a base class Base defined in Base.h : 我在Base.h中定义了一个基类Base

class Base
{ /* ... */ };

And a class template Child that derives from Base , defined in Child.h : 还有一个从Base派生的类模板Child ,它在Child.h中定义:

#include "Base.h"

template <class T>
class Child : public Base
{ /* ... */ };

Now I want to create some factory methods within the Base class, which should return a std::shared_ptr to the Child class. 现在,我想在Base类中创建一些工厂方法,这些方法应将std::shared_ptr返回到Child类。 To avoid circular dependencies I tried to use a forward declaration instead. 为了避免循环依赖,我尝试使用前向声明。 So Base.h now looks like this: 因此, 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);
    }
};

However, the definition of CreateChildInt() leads to the following compiler error: 但是, CreateChildInt()的定义导致以下编译器错误:

"error C2947: expecting '>' to terminate template-argument-list, found '<'" “错误C2947:期望'>'终止模板参数列表,找到'<'”

So is this even possible what I am trying to achieve? 那么,这甚至有可能是我想要达到的目标吗?
If not, are there any workarounds / best practices for this approach? 如果没有,这种方法是否有任何解决方法/最佳做法?

EDIT : The reason for why I want to put the factory method into the Base class instead of Child is the following. 编辑 :为什么我想将工厂方法放入Base类而不是Child的原因如下。 When I put the factory into Child I would need to call the factory method like this: 当我将工厂放入Child我需要像下面这样调用factory方法:

std::shared_ptr<Base> p = Child<int>::CreateChildInt(3);

However, I would like to omit the template type <int> in this call, thus: 但是,我想在此调用中省略模板类型<int> ,因此:

std::shared_ptr<Base> p = Base::CreateChildInt(3);

Firstly, you declared a class, but Child that you define is actually a template. 首先,您声明了一个类,但是您定义的Child实际上是一个模板。 The correct way to declare a class template is: 声明类模板的正确方法是:

template <class T>
class Child;

However, a correct forward declaration alone won't help you. 但是,仅靠正确的前向声明并不能帮助您。 The implementation of CreateChildInt::CreateChildInt must know the full definition of Child because it creates an instance of it. CreateChildInt::CreateChildInt的实现必须知道Child的完整定义,因为它创建了它的实例。 You can't define Child before Base either, because inheritance also depends on the full definition, so you'd end up with a cicrular dependency. 您也不能在Base之前定义Child ,因为继承也取决于完整的定义,因此最终会产生关键的依赖性。

Solution: Forward declare Child , then define Base but don't define Base::CreateChildInt inline, then define Child and finally define Base::CreateChildInt . 解决方案:转发声明Child ,然后定义Base但不要内联定义Base::CreateChildInt ,然后定义Child ,最后定义Base::CreateChildInt


PS. PS。 I find it dubious from OOP perspective that the implementation of the base class member function depends on the child class. 从OOP角度看,我怀疑基类成员函数的实现取决于子类。 I recommend that you consider re-designing your approach. 我建议您考虑重新设计方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM