簡體   English   中英

復制構造函數:深度復制抽象類

[英]Copy constructor: deep copying an abstract class

假設我有以下(簡化的情況):

class Color;

class IColor
{
public: 
    virtual Color getValue(const float u, const float v) const = 0;
};

class Color : public IColor
{
public:
    float r,g,b;
    Color(float ar, float ag, float ab) : r(ar), g(ag), b(ab) {}
    Color getValue(const float u, const float v) const 
    { 
        return Color(r, g, b)
    }
}

class Material
{
private:
    IColor* _color;
public:
    Material();
    Material(const Material& m);
}

現在,有什么方法可以讓我在 Material 的復制構造函數中對抽象 IColor 進行深層復制嗎? 也就是說,我希望復制任何 m._color 的值(顏色、紋理),而不僅僅是指向 IColor 的指針。

你可以在你的界面中添加一個 clone() 函數。

您必須自己將該代碼添加到 Material 復制構造函數中。 然后編碼以釋放析構函數中分配的 IColor。

您還需要向 IColor 添加一個虛擬析構函數。

自動進行深度復制的唯一方法是直接存儲顏色而不是指向 IColor 的指針。

將 clone() 方法添加到顏色可能是最好的,但如果您沒有該選項,另一種解決方案是使用 dynamic_cast 將 IColor* 轉換為 Color*。 然后您可以調用 Color 復制構造函數。

如果您有一個為您創建顏色的“類似工廠”的類,您可以為用戶實現一個類型擦除的向上復制構造函數。 在您的情況下,它可能不適用,但是當它適用時,我發現它比對實現者強制執行克隆功能更優雅。

struct IColor {
    /* ... */

    // One way of using this.
    // If you have a "manager" class, then this can be omitted and completely
    // hidden from IColor implementers.
    std::unique_ptr<IColor> clone() const final {
        return cpy_me(this); // upcasts
    }

    // There are other ways to riff around the idea, but the basics are the same.

private:
    friend struct ColorMaker;

    IColor() = default;

    using cpy_callback_t = std::unique_ptr<IColor> (*)(const IColor*);
    cpy_callback_t cpy_me = nullptr;
};

struct ColorMaker {
    template <class T>
    static std::unique_ptr<IColor> make_color() {
        static_assert(std::is_base_of_v<IColor, T>, "bleep bloop, no can do");

        std::unique_ptr<IColor> ret = std::make_unique<T>();

        // Encoding type T into the callback, type-erasing it.
        // IColor implementer only has to implement copy constructor as usual.
        ret.cpy_me = [](const IColor* from) -> std::unique_ptr<IColor> {
            return std::make_unique<T>(*static_cast<const T*>(from));
        };

        return ret;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM