Maison  >  Article  >  développement back-end  >  Comment puis-je convertir en toute sécurité un « unique_ptr » en un « unique_ptr » en C ?

Comment puis-je convertir en toute sécurité un « unique_ptr » en un « unique_ptr » en C ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-21 19:30:16115parcourir

How can I safely downcast a `unique_ptr` to a `unique_ptr` in C  ?

Downcasting unique_ptr vers unique_ptr

Introduction :

Dans la programmation $texttt{C }$, nous pouvons rencontrer des scénarios dans lesquels nous devons convertir ou « downcaster » un $texttt {unique_ptr}$ d'une classe de base $texttt{Base}$ à un $texttt{unique_ptr}$ d'un dérivé classe $texttt{Dérivé}$. Ce processus implique la conversion du pointeur brut stocké dans $texttt{unique_ptr}$ vers le type dérivé souhaité tout en conservant la sémantique de propriété.

Casting via la libération et la réaffectation :

La question propose une méthode pour libérer l'objet du $texttt{unique_ptr}$, puis convertir le pointeur brut vers le type dérivé souhaité. Cette approche est conceptuellement valide, mais elle présente un inconvénient potentiel : la durée de vie de l'objet est momentanément gérée par un pointeur brut, ce qui pourrait entraîner des fuites de mémoire si l'appelant ne parvient pas à gérer correctement le $texttt{unique_ptr}$ par la suite.

Alternative : diffusion de pointeur unique statique et dynamique :

Pour résoudre ce problème, nous pouvons exploiter la fonction suivante templates :

  • $texttt{static_unique_ptr_cast}$ : effectue un casting statique, en supposant que le pointeur brut est garanti comme étant du type dérivé souhaité.
  • $texttt{dynamic_unique_ptr_cast}$ : effectue diffusion dynamique, en utilisant $texttt{dynamic_cast}$ pour vérifier la diffusion validité.

Mise en œuvre :

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

Utilisation :

Utiliser $texttt{static_unique_ptr_cast}$ lorsque vous êtes certain du type dérivé. Sinon, utilisez $texttt{dynamic_unique_ptr_cast}$ pour vérifier le type correct au moment de l'exécution. Ces fonctions utilisent des références rvalue pour empêcher les modifications involontaires du $texttt{unique_ptr}$ d'origine.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn