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);
// ...
}