如何确保所有派生的C ++ / CLI类都将覆盖基类的ICloneable :: Clone()方法?
你觉得我应该担心吗?或者这不是基类'作家的责任?修正案抱歉,我忘了提及基类是非抽象类。
答案 0 :(得分:2)
在基类中声明它是纯虚拟的。
班级基地
{
...
vitual void克隆()= 0;
};
答案 1 :(得分:2)
好吧,我不能说这是否是基类的责任,并且不会在这里涉及基于继承的合同的风险。
在任何情况下,你都可以强制某些类覆盖一个方法 - 例如,“克隆()”,使其成为抽象类的纯虚拟成员
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中没有克隆覆盖,则会出现编译器错误。
答案 2 :(得分:1)
将Clone()方法声明为abstract。即使父类确实具有具体实现,这也应该有效。
当然,强制执行此类操作的风险在于派生类的编写者会变得恼火,说“我不会再使用Clone”并执行类似字节副本的操作,甚至“返回此” “,摆脱错误。
答案 3 :(得分:1)
如果基类是非抽象的,那么在编译时无法强制它被覆盖。你可以做的最好的事情是:
virtual void Clone()
{
throw gcnew NotSupportedException();
}
使用此方法,派生类必须覆盖该方法,否则您的应用程序将遇到NotSupportedException。这至少会使测试期间的某些内容不正确。它会给你一些东西,以便你知道什么时候遇到一个没有正确覆盖克隆的类。根据您对派生类的控制程度,这对于稳健性非常重要。
答案 4 :(得分:0)
class Base
{
...
virtual void Clone() = 0;
};
是对的。
如果您想要克隆的某些默认行为,请尝试:
class Base
{
...
virtual void Clone()
{
...
doClone();
...
};
...
private:
virtual void doClone() = 0;
};
答案 5 :(得分:0)
修正案抱歉,我忘了提及基类是非抽象类。
在这个新的视角中,我很确定你根本不想强迫任何人覆盖Clone()。例如,如果我的派生类没有添加任何字段,它可能不需要它自己的专用Clone()方法。
答案 6 :(得分:0)
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。
答案 7 :(得分:0)
阅读药草的this。这正是你所要求的
答案 8 :(得分:-1)
托马斯是正确的,但是你将这个类抽象化的一种方法是定义一个纯虚方法。
这是通过说:
来完成的virtual void Clone()= 0;
除非派生类实现了Clone,否则它们将无法实例化它们,因此如果他们希望他们的类有用,他们将没有多少选择。