阻止为每个子类写入克隆方法
Prevent writing clone method for each subclass
这是我的案例:
class A
{
public:
virtual A* clone() = 0;
};
class B : public A
{
virtual B* clone() override
{
return new B();
}
};
在我的代码中,现在A
的100%子类只是以完全相同的方式实现clone
方法——只对类D
——我有返回类型D
,当然我创建了D
的对象。
如何防止这种重复?什么模式或技巧可以帮助你?
我曾想过使用CRTP模式,但它使用模板,而且我的功能是虚拟的。正如我们所理解的,模板和虚拟函数是不兼容的。
NVI模式也不起作用,因为克隆方法的返回类型不同。
[class.virtual]/8:
如果
D::f
的协变返回类型中的类类型与对于B::f
,D::f
的返回类型中的类类型应为在声明D::f
时完成或应为类类型CCD_ 10。
因此,CRTP不能完美地工作,因为引用派生类的模板参数将是一个不完整的类型,因此协变返回类型很难模拟。
然而,这里有一个尝试:
class A
{
public:
virtual A* clone() = 0;
};
namespace detail {
template <typename T>
struct Cloner : A {
using A::A; // For constructors
virtual A* clone() override {return new T;}
};
}
template <typename T>
struct Cloner : detail::Cloner<T> {
using detail::Cloner<T>::Cloner; // For constructors
// For callers
template <class=void>
T* clone() {return static_cast<T*>(detail::Cloner<T>::clone());}
};
class B : public Cloner<B>
{
};
演示。
注意两件事:
返回指向派生类类型的指针的
clone
的重载是一个函数模板。这样我们就不会重写虚拟函数clone
:如果我们重写了,代码就会格式错误,因为返回类型不是协变的(见上文)。因为
clone
是一个函数模板,为了确保它被调用,我们可以让它隐藏虚拟的clone
函数。这是通过继承实现的:派生类中的名称隐藏基类中的名称。因此,如果我们通过B
指针/引用进行调用,我们将获得适当的返回类型(B*
),因为名称是在detail::Cloner
之前的::Cloner
中查找的。
相关文章:
- 从父类方法返回子类对象
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 将子类方法声明为基类的友元
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- C++有没有办法强制重写一组方法,如果其中一个方法在子类中具有重写?
- C ++类型特征:确保子类实现方法
- 函数从唯一代码调用正确的子类方法
- Arduino在子类中使用父类方法
- C++强制在子类中实现方法,但具有不同的签名
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- 如何调用传递给 JNI 'jobject' 的 Java 对象的子类/子类的方法
- 将方法参数类型更改为子类中的派生类
- 如果指针的子类的方法对于子类是唯一的,如何访问这些方法?
- C++继承,如何在基类的方法中调用子类的方法?
- 在子类上调用模板化静态方法时获取类的类型名
- 检查子类是否执行了方法重写
- 将"this"从父类方法转换为子类方法是一种好的做法吗?
- 从C++中的父类实例访问子类方法
- 基类中的虚拟方法和子类中的非 Virtula 方法.仍然如何调用子类方法,即使它是非虚拟的
- C ,基础课程如何将子类作为成员包含并调用其方法