Freigeben über


Warnung C26417

Der Freigegebene Zeigerparameter wird durch Verweis übergeben und nicht zurückgesetzt oder neu zugewiesen. Verwenden Sie stattdessen T* oder T&

C++ Core Guidelines: R.35: Take a shared_ptr<widget>& parameter to express that a function might reseat the shared pointer

Das Übergeben von gemeinsam genutzten Zeigern nach Verweis kann in Szenarien hilfreich sein, in denen das Ziel des intelligenten Zeigerobjekts aktualisiert wird, und der Aufrufer erwartet, dass solche Updates angezeigt werden. Die Verwendung eines Verweises allein zur Reduzierung der Kosten für die Übergabe eines gemeinsamen Zeigers ist fraglich. Wenn der aufgerufene Code nur auf das Zielobjekt zugreift und seine Lebensdauer nie verwaltet, ist es sicherer, einen unformatierten Zeiger oder Verweis zu übergeben, anstatt Ressourcenverwaltungsdetails verfügbar zu machen.

Hinweise

  • Diese Überprüfung erkennt std::shared_pointer und benutzerdefinierte Typen, die sich wahrscheinlich wie freigegebene Zeiger verhalten. Für benutzerdefinierte freigegebene Zeiger werden die folgenden Merkmale erwartet:

  • überladene Ableitungen oder Memberzugriffsoperatoren (öffentlich und nicht gelöscht);

  • einen Kopierkonstruktor oder einen Zuweisungsoperator (öffentlich und nicht gelöscht);

  • ein öffentlicher Destruktor, der nicht gelöscht oder standardmäßig festgelegt ist. Leere Destruktoren werden weiterhin als benutzerdefinierte Gezählt.

  • Die Aktion zum Zurücksetzen oder Erneutes Zuweisen wird allgemeiner interpretiert:

  • jeder Aufruf einer nicht konstanten Funktion für einen freigegebenen Zeiger kann den Zeiger möglicherweise zurücksetzen;

  • Jeder Aufruf einer Funktion, die einen Verweis auf einen nicht konstanten freigegebenen Zeiger akzeptiert, kann diesen Zeiger möglicherweise zurücksetzen oder neu zuweisen.

Beispiele

unnötige Schnittstellenkomplikation

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

unnötige Schnittstellenkomplikation - vereinfacht

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