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