我想让函数clone()
实际上是可重写的,因为我需要它在我的应用程序中是多态的。
class Component
{
virtual Component *cloneImpl() const = 0;
public:
std::unique_ptr<Component> clone() const
{
return std::unique_ptr<Component>(this->cloneImpl());
}
};
到目前为止,我设法做的是将clone()
函数隐藏在一些派生组件中,但这会导致严重的运行时问题。有没有可能让它以一种允许我这样做的方式工作?:
class DerivedComponent : public Component
{
DerivedComponent* cloneImpl() const
{
return new DerivedComponent();
}
public:
std::unique_ptr<DerivedComponent> clone() const override
{
return std::unique_ptr<DerivedComponent>(this->cloneImpl());
}
};
我想使用模板,但不幸的是,这并没有把我带到任何地方。
我希望它是真正多态的,而不仅仅是隐藏基类的clone()
方法。
我担心我想做的事情是不可能的,但我决定值得在这里问一问,只是为了确保我不会浪费更多的时间去想它。
3条答案
按热度按时间pbwdgjma1#
在C++20中,我将使用推导出的公式定义一个隐式CRTP:
static_clone
成员作用于其对象的静态类型,而dynamic_clone
成员基于其对象的动态类型创建新副本。因为整个层次结构是由dynamic_clone
抽象的,所以只能创建Concrete
示例。编辑:
协变
clone
增加了当前示例的静态类型和推断指针的动态类型。clone
和static_clone
也可以实现为static
函数或免费的非成员模板,但这个片段只是一个草率的黑客。hjzp0vay2#
这个怎么样?我只是在猜你在找什么。它并不真正清楚你最终想要什么。.
relj7zay3#
我可能会沿着下面这条主线编写代码:
我应该在这里指出一些可能不太明显的事情:
clone
是类的朋友。由于friend
没有被继承,每个派生类都必须重新声明clone
为其友元。Component
的类定义中,但clone
不是成员函数--因为它是friend
,所以它不能是成员,所以它被“注入”到周围的名称空间(在本例中是全局名称空间)。clone
的 * 声明 *。这意味着clone
只能通过参数相关查找找到。例如,如果我们添加一些不相关的类:...代码将无法编译(即使
Unrelated
)提供了clone
所需的cloneImpl
,因此在其他情况下,它可以工作)。如果你想让它工作,我很确定将friend
声明添加到Unrelated
中会让它工作。unique_ptr<Derived>
,它可以用来调用一个派生特定的函数,而不需要任何类型转换或其他转换。unique_ptr
s)处理相当多的事情--因此我包含了重载,以将输入作为对象或unique_ptr
(两者都向克隆返回unique_ptr
)。