如何强制所有子代覆盖父级的Clone()方法?

时间:2008-09-17 02:22:54

标签: .net c++-cli

如何确保所有派生的C ++ / CLI类都将覆盖基类的ICloneable :: Clone()方法?

你觉得我应该担心吗?或者这不是基类'作家的责任?

修正案抱歉,我忘了提及基类是非抽象类。

9 个答案:

答案 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,否则它们将无法实例化它们,因此如果他们希望他们的类有用,他们将没有多少选择。