Compartir vía


Advertencia C26415

El parámetro de puntero inteligente solo se usa para acceder al puntero contenido. Use T* o T& en su lugar.

C++ Core Guidelines: R.30: Tomar punteros inteligentes como parámetros solo para expresar explícitamente la semántica de duración

El uso de un tipo de puntero inteligente para pasar datos a una función indica que la función de destino debe administrar la duración del objeto contenido. Sin embargo, supongamos que la función solo usa el puntero inteligente para acceder al objeto contenido y nunca llama a ningún código que pueda conducir a su desasignación (es decir, nunca afecta a su duración). A continuación, normalmente no es necesario complicar la interfaz con punteros inteligentes. Se prefiere un puntero o una referencia básicos al objeto contenido.

Comentarios

En esta comprobación se tratan la mayoría de los escenarios que también provocan C26410, C26415, C26417 y C26418. Es mejor limpiar primero SMART_PTR_NOT_NEEDED y, a continuación, cambiar a casos perimetrales para punteros compartidos o únicos. Para una limpieza más centrada, esta advertencia se puede deshabilitar.

Además de las plantillas estándar std::unqiue_pointer y std::shared_pointer, esta comprobación reconoce los tipos definidos por el usuario que probablemente estén diseñados para ser punteros inteligentes. Se espera que estos tipos definan las operaciones siguientes:

  • Operadores de acceso a miembros o de desreferencia sobrecargados que son públicos y no están marcados como eliminados.
  • Destructor público que no se ha eliminado o predeterminado, incluidos los destructores que se definen explícitamente vacíos.

La interpretación de las operaciones que pueden afectar a la duración de los objetos contenidos es amplia e incluye:

  • Cualquier función que acepte un puntero o un parámetro de referencia a un puntero inteligente no constante.
  • Copiar o mover constructores u operadores de asignación.
  • Funciones no constantes.

Ejemplos

Administración complicada de la duración.

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

Administración complicada de la duración: reprocesada.

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