Поделиться через


Предупреждение C26415

Параметр smart pointer используется только для доступа к автономному указателю. Вместо этого используйте T* или T&.

Основные рекомендации по C++ : R.30: использование смарт-указателей в качестве параметров только для явной выражения семантики времени существования

Использование интеллектуального типа указателя для передачи данных в функцию указывает, что целевая функция должна управлять временем существования содержащегося объекта. Тем не менее, говорят, что функция использует только интеллектуальный указатель для доступа к автономному объекту и никогда не вызывает любой код, который может привести к его освобождению (т. е. никогда не влияет на его время существования). Тогда обычно не нужно усложнять интерфейс с помощью смарт-указателей. Предпочтителен обычный указатель или ссылка на содержащийся объект.

Замечания

Эта проверка охватывает большинство сценариев, которые также вызывают C26410, C26415, C26417 и C26418. Лучше сначала очистить SMART_PTR_NOT_NEEDED, а затем переключиться на пограничные варианты для общих или уникальных указателей. Для более ориентированной очистки это предупреждение можно отключить.

Помимо стандартных шаблонов std::unqiue_pointer и std::shared_pointer, эта проверка распознает определяемые пользователем типы, которые, скорее всего, предназначены для смарт-указателей. Предполагается, что такие типы определяют следующие операции:

  • Перегруженные операторы разыменования или доступа к членам, которые являются общедоступными и не помечены как удаленные.
  • Общедоступный деструктор, который не удаляется или не используется по умолчанию, включая деструкторы, которые явно определены пустыми.

Интерпретация операций, которые могут повлиять на время существования содержащихся объектов, широка и включает:

  • Любая функция, принимаюющая указатель или параметр ссылки на неконстантный интеллектуальный указатель
  • Копирование или перемещение конструкторов или операторов назначения
  • Неконстантные функции

Примеры

Громоздкое управление временем существования.

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

Громоздкое управление временем существования — переработано.

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