首頁 >後端開發 >C++ >如何在 C 中安全地將 `unique_ptr` 向下轉換為 `unique_ptr` ?

如何在 C 中安全地將 `unique_ptr` 向下轉換為 `unique_ptr` ?

Barbara Streisand
Barbara Streisand原創
2024-11-19 20:37:03747瀏覽

How to Safely Downcast a `unique_ptr` to `unique_ptr` in C  ?

向下轉型unique_ptr; to unique_ptr

在物件導向程式設計領域,繼承在促進程式碼重用和可繼承擴展性方面發揮關鍵作用。然而,可能會出現需要「向下轉換」unique_ptr的情況。 unique_ptr 的物件對象,可能具有不同的刪除器函數。

為了解決這個挑戰,請考慮一個假設場景,其中應用程式使用多個工廠,每個工廠產生 unique_ptr 。實例。這些工廠可以在內部提供對各種衍生類型的訪問,例如unique_ptr、unique_ptr或unique_ptr。舉例說明:

unique_ptr<Base> DerivedAFactory() {
    return unique_ptr<Base>(new DerivedA);
}

目標是將傳回的 unique_ptr 內的指標轉換為衍生型別,即使它與原始內部型別不同。人們可以用偽代碼想像這個過程:

unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());

但是,這種方法有潛在的陷阱。更穩健的解決方案涉及從 unique_ptr 釋放對象,將原始指標轉換為所需的派生類型,並將其重新指派給新的 unique_ptr 類型。使用適當的刪除器。

unique_ptr<Derived> CastToDerived(Base* obj) {
    return unique_ptr<Derived>(static_cast<Derived*>(obj));
}

只要物件從 DLL 動態載入並從相同上下文釋放,此轉換過程就應該保持有效。但是,在不同上下文之間轉移所有權時,必須注意在指標旁邊提供正確的刪除器。

為了增加安全性和靈活性,建議使用函數模板進行轉換:

template<typename Derived, typename Base, typename Del>
std::unique_ptr<Derived, Del> 
static_unique_ptr_cast( std::unique_ptr<Base, Del>&& p )
{
    auto d = static_cast<Derived *>(p.release());
    return std::unique_ptr<Derived, Del>(d, std::move(p.get_deleter()));
}

template<typename Derived, typename Base, typename Del>
std::unique_ptr<Derived, Del> 
dynamic_unique_ptr_cast( std::unique_ptr<Base, Del>&& p )
{
    if(Derived *result = dynamic_cast<Derived *>(p.get())) {
        p.release();
        return std::unique_ptr<Derived, Del>(result, std::move(p.get_deleter()));
    }
    return std::unique_ptr<Derived, Del>(nullptr, p.get_deleter());
}

這些模板確保傳遞的unique_ptr 不會無意中從呼叫者那裡竊取,同時提供靜態和動態轉換選項。當已知指標是派生*而無需動態轉換時,可以使用靜態版本,而動態版本使用dynamic_cast執行運行時檢查。

以上是如何在 C 中安全地將 `unique_ptr` 向下轉換為 `unique_ptr` ?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn