如何確保所有派生的C++/CLI類都會覆蓋基類的ICloneable :: Clone()方法?如何強制所有孩子重寫父母的Clone()方法?
你認爲我應該擔心這個嗎?或者這不是基類作家的責任?
修訂:對不起,我忘記提及基類是一個非抽象類。
如何確保所有派生的C++/CLI類都會覆蓋基類的ICloneable :: Clone()方法?如何強制所有孩子重寫父母的Clone()方法?
你認爲我應該擔心這個嗎?或者這不是基類作家的責任?
修訂:對不起,我忘記提及基類是一個非抽象類。
將Clone()方法聲明爲abstract。即使父類有具體的實現,這也應該工作。
當然,執行此類事情時的風險是派生類的作者會變得惱火,比如說「我不打算使用克隆」,並執行類似於字節複製或甚至「返回這個「,以擺脫錯誤。
在基類中聲明純虛擬。
類基地
{
...
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克隆覆蓋,你得到一個編譯錯誤。
托馬斯是正確的,但你會讓這個類抽象的一種方法是定義一個純粹的虛擬方法。
這是通過說:
virtual void Clone()= 0;
除非派生類實現克隆,否則它們將無法實例化它,因此如果他們希望自己的類有用,他們將沒有多少選擇。
class Base
{
...
virtual void Clone() = 0;
};
是正確的。
如果你想要克隆的一些默認行爲,請嘗試:
class Base
{
...
virtual void Clone()
{
...
doClone();
...
};
...
private:
virtual void doClone() = 0;
};
修訂:對不起,我忘了提,基類是一個非抽象類。
在這個新的燈光中,我敢肯定你不想強迫任何人重寫Clone()。例如,如果我的派生類沒有添加任何字段,它可能不需要它自己的專用Clone()方法。
如果基類是非抽象的,那麼有沒有辦法迫使它在編譯時被覆蓋。你也許可以做的最好的是一樣的東西:
virtual void Clone()
{
throw gcnew NotSupportedException();
}
由此,派生類必須覆蓋的方法或您的應用程序會遇到一個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如果嘗試克隆尚未覆蓋基類的clone()方法派生類的一個實例。
閱讀this通過草藥sutter。這正是你要求的
即使你的派生類沒有添加任何新的字段,ICloneable :: Clone()方法仍然需要創建並返回一個正確類型的對象。 baseClassObj-> Clone()應該返回一個BaseClass的實例,derivedClassObj-> Clone()應該返回一個DerivedClass的實例。 – metamal 2008-09-17 04:29:56