Sdílet prostřednictvím


Upozornění C26415

Parametr inteligentního ukazatele se používá pouze pro přístup k obsaženému ukazateli. Místo toho použijte T* nebo T&.

C++ Core Guidelines: R.30: Vezměte inteligentní ukazatele jako parametry pouze k explicitní vyjádření sémantiky životnosti

Použití typu inteligentního ukazatele k předání dat do funkce označuje, že cílová funkce potřebuje spravovat životnost obsaženého objektu. Řekněme však, že funkce používá pouze inteligentní ukazatel pro přístup k obsaženému objektu a nikdy ve skutečnosti nevolá žádný kód, který může vést k jeho uvolnění (to znamená, že nikdy nemá vliv na jeho životnost). Pak není obvykle nutné komplikovat rozhraní inteligentními ukazateli. Preferuje se prostý ukazatel nebo odkaz na obsažený objekt.

Poznámky

Tato kontrola popisuje většinu scénářů, které také způsobují C26410, C26415, C26417 a C26418. Nejprve je lepší vyčistit SMART_PTR_NOT_NEEDED a pak přepnout na hraniční případy pro sdílené nebo jedinečné ukazatele. Pro konkrétnější vyčištění může být toto upozornění zakázané.

Kromě standardních šablon std::unqiue_pointer a std::shared_pointer tato kontrola rozpozná uživatelem definované typy, které mají být pravděpodobně inteligentními ukazateli. Očekává se, že tyto typy definují následující operace:

  • Přetížené dereference nebo operátory přístupu členů, které jsou veřejné a nejsou označeny jako odstraněné.
  • Veřejný destruktor, který není odstraněný nebo výchozí, včetně destruktorů, které jsou explicitně definované prázdné.

Interpretace operací, které mohou ovlivnit životnost obsažených objektů, je široká a zahrnuje:

  • Libovolná funkce, která přijímá ukazatel nebo odkaz na nekontinutní inteligentní ukazatel
  • Kopírování nebo přesunutí konstruktorů nebo operátorů přiřazení
  • Ne constantní funkce

Příklady

Těžkopádná správa životního cyklu.

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

Těžkopádná správa životního cyklu – přepracováno.

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