すべての派生C++/CLIクラスが基本クラスのICloneable :: Clone()メソッドをオーバーライドする方法を確認するにはどうすればよいですか?すべての子に親のClone()メソッドをオーバーライドする方法を教えてください。
私はこれについて心配すべきだと思いますか?または、これはベースクラスの作家の責任ではありませんか?
修正:申し訳ありませんが、基本クラスは抽象クラスではありません。
すべての派生C++/CLIクラスが基本クラスのICloneable :: Clone()メソッドをオーバーライドする方法を確認するにはどうすればよいですか?すべての子に親のClone()メソッドをオーバーライドする方法を教えてください。
私はこれについて心配すべきだと思いますか?または、これはベースクラスの作家の責任ではありませんか?
修正:申し訳ありませんが、基本クラスは抽象クラスではありません。
抽象としてClone()メソッドを宣言します。これは、親クラスが具体的な実装を持っている場合でも動作するはずです。
もちろん、そのようなことを強制するときのリスクは、派生クラスの作者が、「私はクローンをとにかく使うつもりはない」と言って、バイトコピー、あるいは「返品」これは、エラーを取り除くために、 "。
基本クラスでpure virtualを宣言します。
クラスベース
{
...
vitualボイドクローン()= 0;
};
これは基本クラスの責任であるかどうかはわかりませんが、ここでは継承ベースの契約の危険に陥ることはありません。いずれの場合においても
、あなたはメソッドをオーバーライドするためにいくつかのクラスを強制することができます - 「クローン()」例えば、その抽象クラスの純粋仮想メンバー
public ref class ClonableBase abstract
{
public:
virtual void Clone() = 0;
}
ノート行うことで"抽象的な"と "= 0;"抽象クラスでは、クラスに警告なしで純粋な仮想メンバを含めることができ、= 0;このメソッドが純粋な仮想であることを意味します。つまり、ボディが含まれていません。抽象クラスをインスタンス化することはできません。
今あなたができる
public ref class ClonableChild : public ClonableBase
{
public:
virtual void Clone();
}
void ConableChild::Clone()
{
//some stuff here
}
あなたはClonableChildにおけるクローンのオーバーライドを持っていない場合、あなたはコンパイラエラーを取得します。
Thomasは正解ですが、そのクラスを抽象化する方法の1つは、純粋な仮想メソッドを定義することです。
これは言って行われます。
仮想ボイドクローン()= 0;
派生クラスがCloneを実装していない限り、クラスをインスタンス化することができないため、クラスを有用にしたい場合はほとんど選択肢がありません。
class Base
{
...
virtual void Clone() = 0;
};
が正しい。あなたはクローンのためのいくつかのデフォルトの動作が必要な場合
、試してみてください。
class Base
{
...
virtual void Clone()
{
...
doClone();
...
};
...
private:
virtual void doClone() = 0;
};
改正:申し訳ありませんが、私は、基本クラスは非抽象クラスであることを言及するのを忘れてしまいました。
この新しいライトでは、誰も強制的にクローン()をオーバーライドしたくないと確信しています。たとえば、派生したクラスがフィールドを追加しない場合、おそらく独自の特殊なClone()メソッドは必要ありません。
基本クラスが非抽象クラスの場合、コンパイル時に強制的にオーバーライドする方法はありません。あなたはおそらくできる最善のようなものである。これにより
virtual void Clone()
{
throw gcnew NotSupportedException();
}
、派生クラスは、メソッドまたはアプリケーションが非サポート例外が発生しますオーバーライドする必要があります。これは少なくとも、テスト中に何かが間違っていることがすぐに明らかになります。クローンを正しく上書きしなかったクラスに遭遇したときにわかるように、何かを探すことができます。あなたが派生したクラスに対してどの程度の制御力を持っているかによって、これは堅牢性にとって重要になります。
いくつか熟考した後、私はこの解決策を見つけた:
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;
}
あなたは、基本クラスのクローン()メソッドをオーバーライドしていない派生クラスのインスタンスを複製しようとすると、それはNotImplementedExceptionをスローします。
this by herb sutter。それはまさにあなたが求めているものです
派生クラスが新しいフィールドを追加しない場合でも、ICloneable :: Clone()メソッドは正しいタイプのオブジェクトを作成して返す必要があります。 baseClassObj-> Clone()はBaseClassのインスタンスを返し、derivedClassObj-> Clone()はDerivedClassのインスタンスを返すべきです。 – metamal