如何确保所有派生的 C++/CLI 类将覆盖基类的 ICloneable::Clone() 方法?
你觉得我应该担心这个吗?或者这不是基类作者的责任?
修正:对不起,我忘了提到基类是一个非抽象类。
在基类中声明它是纯虚拟的。
类 Base
{
...
vitual void Clone() = 0;
};
好吧,我不能说这是否是基类的责任,也不会在这里讨论基于继承的合同的危险。
在任何情况下,您都可以强制某个类覆盖一个方法 - 例如,“Clone()”,通过使其成为抽象类的纯虚拟成员
public ref class ClonableBase abstract
{
public:
virtual void Clone() = 0;
}
注意“abstract”和“=0;”。抽象允许类在没有警告的情况下包含纯虚拟成员,并且 =0; 意味着这个方法是纯虚拟的——也就是说,它不包含主体。请注意,您不能实例化抽象类。
现在你可以
public ref class ClonableChild : public ClonableBase
{
public:
virtual void Clone();
}
void ConableChild::Clone()
{
//some stuff here
}
如果您在 ClonableChild 中没有 Clone 覆盖,则会出现编译器错误。
将 Clone() 方法声明为抽象的。即使父类确实有具体的实现,这也应该有效。
当然,执行此类操作时的风险是派生类的编写者会生气,说“我无论如何也不打算使用 Clone”并执行字节复制,甚至“返回 this”之类的操作,以摆脱错误。
如果基类是非抽象的,那么就没有办法在编译时强制它被覆盖。您可能做的最好的事情是:
virtual void Clone()
{
throw gcnew NotSupportedException();
}
这样,派生类将不得不重写该方法,否则您的应用程序将遇到 NotSupportedException。这至少会在测试过程中立即表明某些地方不正确。它会给你一些寻找的东西,以便你知道什么时候遇到一个没有正确覆盖克隆的类。根据您对派生类的控制程度,这对于稳健性可能很重要。
class Base
{
...
virtual void Clone() = 0;
};
是正确的。
如果您想要克隆的一些默认行为,请尝试:
class Base
{
...
virtual void Clone()
{
...
doClone();
...
};
...
private:
virtual void doClone() = 0;
};
由草本萨特阅读。这正是你要问的
修正:对不起,我忘了提到基类是一个非抽象类。
从这个新角度来看,我很确定您根本不想强迫任何人覆盖 Clone()。例如,如果我的派生类不添加任何字段,它可能不需要自己的专用 Clone() 方法。
经过一番思考,我找到了这个解决方案:
Object^ BaseClass::Clone()
{
if(this->GetType() != BaseClass::typeid)
{
throw gcnew System::NotImplementedException("The Clone() method is not implemented for " + this->GetType()->ToString() + "!");
}
BaseClass^ base = gcnew BaseClass();
... // Copy the fields here
return base;
}
如果您尝试克隆尚未覆盖基类的 Clone() 方法的派生类的实例,则会引发 NotImplementedException。
Thomas 是正确的,但是使该类抽象的一种方法是定义一个纯虚拟方法。
这是通过说:
虚拟无效克隆()= 0;
除非派生类实现 Clone,否则他们将无法实例化它,因此如果他们希望自己的类有用,他们将别无选择。