Aviso C26415
O parâmetro de ponteiro inteligente é usado apenas para acessar o ponteiro contido. Em vez disso, use T* ou T& em vez disso.
Diretrizes Principais do C++: R.30: Use ponteiros inteligentes como parâmetros apenas para expressar explicitamente a semântica de tempo de vida
Usar um tipo de ponteiro inteligente para passar dados para uma função indica que a função de destino precisa gerenciar o tempo de vida do objeto contido. No entanto, digamos que a função usa apenas o ponteiro inteligente para acessar o objeto contido e nunca realmente chama qualquer código que possa levar à sua desalocação (ou seja, nunca afeta sua vida útil). Então, geralmente não há necessidade de complicar a interface com ponteiros inteligentes. É preferível um ponteiro simples ou uma referência ao objeto contido.
Comentários
Essa verificação abrange a maioria dos cenários que também causam C26410, C26415, C26417 e C26418. É melhor limpar SMART_PTR_NOT_NEEDED primeiro e, em seguida, alternar para casos de borda para ponteiros compartilhados ou exclusivos. Para uma limpeza mais focada, esse aviso pode ser desabilitado.
Além dos modelos padrão std::unqiue_pointer e std::shared_pointer, essa verificação reconhece tipos definidos pelo usuário que tenham probabilidade de ser ponteiros inteligentes. Esses tipos devem definir as seguintes operações:
- Operadores de acesso de membro ou de desreferência sobrecarregados que são públicos e não marcados como excluídos.
- Destruidor público que não é excluído ou padrão, incluindo destruidores que são explicitamente definidos vazios.
A interpretação das operações que podem afetar o tempo de vida dos objetos contidos é ampla e inclui:
- Qualquer função que aceite um ponteiro ou parâmetro de referência para um ponteiro inteligente não constante
- Copiar ou mover construtores ou operadores de atribuição
- Funções não constantes
Exemplos
Gerenciamento de tempo de vida complicado.
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();
}
Gerenciamento de tempo de vida complicado – retrabalhado.
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);
// ...
}