Condividi tramite


Avviso C26415

Il parametro del puntatore intelligente viene usato solo per accedere al puntatore indipendente. In alternativa, usare T* o T& .

Linee guida di base di C++: R.30: Prendere puntatori intelligenti come parametri solo per esprimere in modo esplicito la semantica della durata

L'uso di un tipo di puntatore intelligente per passare dati a una funzione indica che la funzione di destinazione deve gestire la durata dell'oggetto contenuto. Tuttavia, si supponga che la funzione usi solo il puntatore intelligente per accedere all'oggetto contenuto e non chiami mai alcun codice che possa portare alla deallocazione , ovvero non influisce mai sulla sua durata. In genere non c'è bisogno di complicare l'interfaccia con puntatori intelligenti. È preferibile un puntatore o un riferimento normale all'oggetto contenuto.

Osservazioni:

Questo controllo riguarda la maggior parte degli scenari che causano anche C26410, C26415, C26417 e C26418. È preferibile pulire prima SMART_PTR_NOT_NEEDED e quindi passare ai case perimetrali per puntatori condivisi o univoci. Per una pulizia più mirata, questo avviso può essere disabilitato.

Oltre ai modelli standard std::unqiue_pointer e std::shared_pointer, questo controllo riconosce i tipi definiti dall'utente che probabilmente devono essere puntatori intelligenti. Tali tipi devono definire le operazioni seguenti:

  • Dereferenziazione in overload o operatori di accesso ai membri pubblici e non contrassegnati come eliminati.
  • Distruttore pubblico non eliminato o predefinito, inclusi distruttori definiti in modo esplicito vuoto.

L'interpretazione delle operazioni che possono influire sulla durata degli oggetti contenuti è ampia e include:

  • Qualsiasi funzione che accetta un puntatore o un parametro di riferimento a un puntatore intelligente non costante
  • Copiare o spostare costruttori o operatori di assegnazione
  • Funzioni non costanti

Esempi

Gestione della durata complessa.

bool set_initial_message(
            const std::unique_ptr<message> &m) // C26415, also C26410 NO_REF_TO_CONST_UNIQUE_PTR
{
    if (!m || initial_message_)
        return false;

    initial_message_.reset(m.get());
    return true;
}

void pass_message(const message_info &info)
{
    auto m = std::make_unique<message>(info);
    const auto release = set_initial_message(m);
    // ...
    if (release)
        m.release();
}

Gestione della durata complessa: rielaborata.

void set_initial_message(std::shared_ptr<message> m) noexcept
{
    if (m && !initial_message_)
        initial_message_ = std::move(m);
}

void pass_message(const message_info &info)
{
    auto m = std::make_shared<message>(info);
    set_initial_message(m);
    // ...
}