Megosztás:


Figyelmeztetés C26415

Az okos mutató paraméter csak a tartalmazott mutató elérésére szolgál. Használja inkább a T* vagy a T> elemet.

C++ alapvető irányelvek: R.30: Az intelligens mutatókat csak paraméterekként használva explicit módon fejezze ki az élettartam szemantikáját

Ha intelligens mutatótípussal ad át adatokat egy függvénynek, az azt jelzi, hogy a célfüggvénynek kezelnie kell a tárolt objektum élettartamát. Tegyük fel azonban, hogy a függvény csak az okos mutatót használja a tartalmazott objektum eléréséhez, és soha nem hív meg olyan kódot, amely a felszabadításához vezethet (vagyis soha nem befolyásolja annak az élettartamát). Ezután általában nincs szükség a felület intelligens mutatókkal való bonyolítására. Előnyben részesítendő egy egyszerű mutató vagy hivatkozás a tartalmazott objektumra.

Megjegyzések

Ez az ellenőrzés lefedi a legtöbb olyan forgatókönyvet, amely a C26410, C26415, C26417 és C26418 hibákat is okozza. Jobb, ha először megtisztítja SMART_PTR_NOT_NEEDED, majd a megosztott vagy egyedi mutatók éles eseteire vált. A szűrtebb törlés érdekében ez a figyelmeztetés letiltható.

A szabványos std::unqiue_pointer és std::shared_pointer sablonok mellett ez az ellenőrzés felismeri a felhasználó által definiált, valószínűleg intelligens mutatónak szánt típusokat. Az ilyen típusok várhatóan a következő műveleteket határozzák meg:

  • Túlterhelt referencia vagy tagelérési operátorok, amelyek nyilvánosak és nincs töröltként megjelölve.
  • Nyilvános destruktor, amelyet nem töröltek vagy nem alapértelmezett, beleértve azokat a destruktorokat is, amelyek kifejezetten üresen vannak definiálva.

A tartalmazott objektumok élettartamát befolyásoló műveletek értelmezése széles körű, és a következőket foglalja magában:

  • Minden olyan függvény, amely nem állandó intelligens mutatóra mutató mutatót vagy referenciaparamétert fogad el
  • Konstruktorok vagy hozzárendelési operátorok másolása vagy áthelyezése
  • Nem állandó függvények

Példák

Nehézkes élettartam-kezelés.

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

Nehézkes életciklus-kezelés – átdolgozva.

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