Heim >Backend-Entwicklung >C++ >Wie kann man in C einen „unique_ptr' sicher in „unique_ptr' umwandeln?

Wie kann man in C einen „unique_ptr' sicher in „unique_ptr' umwandeln?

Barbara Streisand
Barbara StreisandOriginal
2024-11-19 20:37:03747Durchsuche

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

Downcasting unique_ptr to unique_ptr

Im Bereich der objektorientierten Programmierung spielt Vererbung eine entscheidende Rolle bei der Förderung der Wiederverwendung und Erweiterbarkeit von Code. Es können jedoch Situationen auftreten, in denen ein unique_ptr-Wert „heruntergestuft“ werden muss. Objekt zu einem unique_ptr Objekt, möglicherweise mit einer anderen Löschfunktion.

Um dieser Herausforderung zu begegnen, stellen Sie sich ein hypothetisches Szenario vor, in dem eine Anwendung mehrere Fabriken verwendet, von denen jede unique_ptr erzeugt. Instanzen. Diese Fabriken können intern Zugriff auf verschiedene abgeleitete Typen bieten, z. B. unique_ptr, unique_ptr oder unique_ptr. Zur Veranschaulichung:

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

Das Ziel besteht darin, den Zeiger innerhalb des zurückgegebenen unique_ptr umzuwandeln. zu einem abgeleiteten Typ, auch wenn dieser vom ursprünglichen internen Typ abweicht. Man kann sich diesen Prozess in Pseudocode vorstellen:

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

Dieser Ansatz birgt jedoch potenzielle Fallstricke. Eine robustere Lösung besteht darin, das Objekt aus dem unique_ptr freizugeben, den Rohzeiger auf den gewünschten abgeleiteten Typ umzuwandeln und ihn einem neuen unique_ptr-Typ neu zuzuweisen. mit einem geeigneten Löscher.

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

Dieser Umwandlungsprozess sollte gültig bleiben, solange das Objekt dynamisch aus einer DLL geladen und aus demselben Kontext freigegeben wird. Bei der Übertragung des Eigentums über verschiedene Kontexte hinweg muss jedoch darauf geachtet werden, neben dem Zeiger ein korrektes Löschzeichen anzugeben.

Für zusätzliche Sicherheit und Flexibilität wird empfohlen, Funktionsvorlagen für die Umwandlung zu verwenden:

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

Diese Vorlagen stellen sicher, dass der übergebene unique_ptr nicht unbeabsichtigt vom Aufrufer gestohlen wird, und bieten gleichzeitig sowohl statische als auch dynamische Casting-Optionen. Die statische Version kann verwendet werden, wenn bekannt ist, dass der Zeiger ein abgeleiteter * ohne dynamische Umwandlung ist, während die dynamische Version eine Laufzeitprüfung mithilfe von „dynamic_cast“ durchführt.

Das obige ist der detaillierte Inhalt vonWie kann man in C einen „unique_ptr' sicher in „unique_ptr' umwandeln?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn