Compartir vía


Advertencia C26417

El parámetro de puntero compartido se pasa por referencia y no se restablece ni reasigna. Use T* o T& en su lugar.

Directrices básicas de C++: R.35: Tomar un<shared_ptr widget> & parámetro para expresar que una función podría volver a colocar el puntero compartido

Pasar punteros compartidos por referencia puede ser útil en escenarios en los que el código llamado actualiza el destino del objeto de puntero inteligente y su llamador espera ver dichas actualizaciones. El uso de una referencia con el único propósito de reducir los costos de pasar un puntero compartido es cuestionable. Si el código al que se llama solo tiene acceso al objeto de destino y nunca administra su duración, es más seguro pasar un puntero o referencia sin procesar, en lugar de exponer los detalles de administración de recursos.

Comentarios

  • Esta comprobación reconoce std::shared_pointer y los tipos definidos por el usuario que probablemente se comporten como punteros compartidos. En los punteros compartidos definidos por el usuario se esperan los rasgos siguientes:

  • operadores de acceso a miembros o de desreferencia sobrecargados (públicos y no eliminados);

  • un constructor de copia o un operador de asignación de copia (público y no eliminado);

  • Un destructor público que no esté eliminado o sea el predeterminado. Los destructores vacíos todavía cuentan como definidos por el usuario.

  • La acción de restablecer o reasignar se interpreta de forma más genérica:

  • Cualquier llamada a una función no constante en un puntero compartido puede restablecer el puntero.

  • cualquier llamada a una función que acepte una referencia a un puntero compartido que no sea constante puede restablecer o reasignar ese puntero.

Ejemplos

complicación innecesaria de la interfaz

bool unregister(std::shared_ptr<event> &e) // C26417, also C26415 SMART_PTR_NOT_NEEDED
{
    return e && events_.erase(e->id());
}

void renew(std::shared_ptr<event> &e)
{
    if (unregister(e))
        e = std::make_shared<event>(e->id());
    // ...
}

complicación innecesaria de la interfaz: simplificado

bool unregister(const event *e)
{
    return e && events_.erase(e->id());
}

void renew(std::shared_ptr<event> &e)
{
    if (unregister(e.get()))
        e = std::make_shared<event>(e->id());
    // ...
}