我有以下設定:
class Base {
private:
// data members
public:
// methods
// pure virtual methods
virtual Base* clone() const =0;
}
class Derived : public Base{
private:
// more data members
public:
// more methods
// pure virtual methods overridden
Derived* clone() const override{
return new Derived(*this);
}
我現在想介紹一個新的派生類,在裝飾器模式的背景關系中,它有一個指向基類物件的唯一指標作為資料成員。我的問題是如何正確實作 clone() 方法,因為“標準”實作會導致編譯時錯誤,因為無法復制唯一指標:
class DecoratedDerived : public Base{
private:
unique_ptr<Base> ptr;
// more data members
public:
// more methods
// pure virtual methods overridden
DecoratedDerived* clone() const override{
return new DecoratedDerived(*this); // compiler error
}
一種解決方案是在 clone 方法中構造一個新的 DecoratedDerived 類物件(通過顯式深度復制與當前物件關聯的所有成員),然后傳遞一個指向 this 的指標。但是,如果班級有很多其他成員,這將非常耗時。
我還應該說我只使用了一個唯一指標,因為這似乎是現代 C 中使用的標準智能指標。特別是在我使用 C 11 之前,我剛剛設計了自己的智能指標,它負責所有的記憶體管理等,因此對于這種型別的智能指標,裝飾類中的 clone 方法不會有問題。
在此先感謝您的幫助!
uj5u.com熱心網友回復:
只需向該資料成員添加一個復制建構式DecoratedDerived,clone()例如:
class DecoratedDerived : public Base {
private:
unique_ptr<Base> ptr;
// ...
public:
DecoratedDerived(const DecoratedDerived &src)
: Base(src), ptr(src.ptr ? src.ptr->clone() : nullptr)
{
}
// ...
DecoratedDerived* clone() const override{
return new DecoratedDerived(*this);
}
};
在線演示
uj5u.com熱心網友回復:
這是可能的實作,當新DecoratedDerived構造的成員項也被克隆時:
class Base {
public:
virtual std::unique_ptr<Base> clone() const = 0;
};
class Empty : public Base {
public:
std::unique_ptr<Base> clone() const override {
return std::make_unique<Empty>();
}
};
class DecoratedDerived : public Base {
private:
std::unique_ptr<Base> ptr;
public:
DecoratedDerived() : ptr{std::make_unique<Empty>()} {}
DecoratedDerived(std::unique_ptr<Base> wrap) : ptr{std::move(wrap)} {}
std::unique_ptr<Base> clone() const override {
return std::make_unique<DecoratedDerived>(ptr->clone());
}
};
https://godbolt.org/z/sG3zTehb1
Emptyclass 是避免檢查nullptr.
另請注意,由于您正在使用unique_ptr我已經在其他地方介紹它們似乎合乎邏輯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/462794.html
上一篇:C語言中指標的最佳實踐
