gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:00:14 24 4
gpt4 key购买 nike

我有一个基类 BaseBase.h中定义:

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

还有一个类模板Child源自 Base ,在 Child.h 中定义:

#include "Base.h"

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

现在我想在 Base 中创建一些工厂方法类,它应该返回一个 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()的定义导致以下编译器错误:

“错误 C2947:期待‘>’终止模板参数列表,找到‘<’”

那么这是否有可能实现我想要实现的目标?
如果没有,这种方法是否有任何解决方法/最佳实践?

编辑:之所以要把工厂方法放到Base里面类而不是 Child是以下。当我把工厂放进Child我需要像这样调用工厂方法:

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

但是,我想省略模板类型 <int>在这个调用中,因此:

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

最佳答案

首先,你声明了一个类,但是你定义的Child其实是一个模板。声明类模板的正确方法是:

template <class T>
class Child;

但是,仅靠正确的前向声明对您没有帮助。 CreateChildInt::CreateChildInt 的实现必须知道 Child 的完整定义,因为它创建了它的一个实例。你也不能在 Base 之前定义 Child,因为继承也依赖于完整的定义,所以你最终会得到一个循环依赖。

解决方案:前向声明Child,然后定义Base,但不要内联定义Base::CreateChildInt,然后定义Child 最后定义 Base::CreateChildInt


附言。从 OOP 的角度来看,我觉得基类成员函数的实现依赖于子类是可疑的。我建议您考虑重新设计您的方法。

关于c++ - 如何在共享指针中为模板类使用前向声明(在 C++ 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40965187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com