Warnung C26415

Der Intelligente Zeigerparameter wird nur für den Zugriff auf enthaltene Zeiger verwendet. Verwenden Sie stattdessen T* oder T&

C++-Kernrichtlinien: R.30: Verwenden Sie intelligente Zeiger als Parameter, um die Lebensdauersemantik explizit auszudrücken.

Die Verwendung eines intelligenten Zeigertyps zum Übergeben von Daten an eine Funktion gibt an, dass die Zielfunktion die Lebensdauer des enthaltenen Objekts verwalten muss. Sagen Sie jedoch, dass die Funktion nur den intelligenten Zeiger verwendet, um auf das enthaltene Objekt zuzugreifen, und ruft niemals code auf, der zu seiner Deallocation führen kann (d. a. Dann ist es in der Regel nicht erforderlich, die Schnittstelle mit intelligenten Zeigern zu komplizieren. Ein einfacher Zeiger oder Verweis auf das enthaltene Objekt wird bevorzugt.

Hinweise

Diese Überprüfung behandelt die meisten Szenarien, die auch C26410, C26415, C26417 und C26418 verursachen. Es ist besser, zuerst SMART_PTR_NOT_NEEDED sauber und dann zu Edge-Fällen für freigegebene oder eindeutige Zeiger zu wechseln. Für gezieltere sauber up kann diese Warnung deaktiviert werden.

Neben den Standardvorlagen "std::unqiue_pointer" und "std::shared_pointer" erkennt diese Überprüfung benutzerdefinierte Typen, die wahrscheinlich intelligente Zeiger sein sollen. Solche Typen werden erwartet, dass die folgenden Vorgänge definiert werden:

  • Überladene Ableitung oder Memberzugriffsoperatoren, die öffentlich sind und nicht als gelöscht markiert sind.
  • Öffentlicher Destruktor, der nicht gelöscht oder standardmäßig gelöscht wird, einschließlich Destruktoren, die explizit leer definiert sind.

Die Interpretation der Vorgänge, die sich auf die Lebensdauer der enthaltenen Objekte auswirken können, ist breit und umfasst:

  • Jede Funktion, die einen Zeiger oder Verweisparameter auf einen nicht konstanten intelligenten Zeiger akzeptiert
  • Kopieren oder Verschieben von Konstruktoren oder Zuordnungsoperatoren
  • Nichtkonstante Funktionen

Beispiele

Umständliche Lebensdauerverwaltung.

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

Umständliches Lebensmanagement - überarbeitet.

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