Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Menurunkan `unique_ptr` kepada `unique_ptr` dengan selamat dalam C ?

Bagaimana untuk Menurunkan `unique_ptr` kepada `unique_ptr` dengan selamat dalam C ?

Barbara Streisand
Barbara Streisandasal
2024-11-19 20:37:03745semak imbas

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

Menurunkan unique_ptr to unique_ptr

Dalam bidang pengaturcaraan berorientasikan objek, warisan memainkan peranan penting dalam memupuk penggunaan semula dan kebolehlanjutan kod. Walau bagaimanapun, situasi mungkin timbul di mana seseorang perlu "menurunkan" satu_ptr membantah kepada unik_ptr objek, berpotensi dengan fungsi pemadam yang berbeza.

Untuk menangani cabaran ini, pertimbangkan senario hipotetikal di mana aplikasi menggunakan beberapa kilang, setiap satu menghasilkan_ptr contoh. Kilang-kilang ini secara dalaman mungkin menawarkan akses kepada pelbagai jenis terbitan, seperti unique_ptr, unique_ptr atau unique_ptr. Untuk menggambarkan:

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

Matlamatnya adalah untuk menukar penuding dalam unique_ptr kepada jenis terbitan, walaupun ia berbeza daripada jenis dalaman asal. Seseorang boleh membayangkan proses ini dalam pseudokod:

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

Walau bagaimanapun, pendekatan ini menunjukkan kemungkinan perangkap. Penyelesaian yang lebih mantap melibatkan pelepasan objek daripada unique_ptr, menghantar penuding mentah kepada jenis terbitan yang diingini dan menugaskannya semula kepada unique_ptr dengan pemadam yang sesuai.

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

Proses pemutus ini harus kekal sah selagi objek dimuatkan secara dinamik daripada DLL dan dikeluarkan daripada konteks yang sama. Walau bagaimanapun, apabila memindahkan pemilikan merentas konteks yang berbeza, seseorang mesti berhati-hati untuk membekalkan pemadam yang betul bersama penuding.

Untuk keselamatan dan fleksibiliti tambahan, adalah disyorkan untuk menggunakan templat fungsi untuk menghantar:

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());
}

Templat ini memastikan unik_ptr yang diluluskan tidak dicuri secara tidak sengaja daripada pemanggil sambil menyediakan kedua-dua pilihan penghantaran statik dan dinamik. Versi statik boleh digunakan apabila penuding diketahui sebagai Terbitan * tanpa penghantaran dinamik, manakala versi dinamik melakukan semakan masa jalan menggunakan dynamic_cast.

Atas ialah kandungan terperinci Bagaimana untuk Menurunkan `unique_ptr` kepada `unique_ptr` dengan selamat dalam C ?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn