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


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

Общий параметр указателя передается по ссылке, а не сбрасывается или переназначается. Вместо этого используйте T* или T&.

Основные рекомендации по C++ : R.35: примите параметр мини-приложения> shared_ptr<, чтобы выразить, что функция может повторно изменить общий указатель

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

Замечания

  • Эта проверка распознает std::shared_pointer и определяемые пользователем типы, которые, скорее всего, будут вести себя как общие указатели. Для определяемых пользователем общих указателей ожидаются следующие признаки:

  • перегруженные операторы деконференции или доступа к членам (общедоступные и не удаленные);

  • конструктор копирования или оператор назначения копирования (открытый и не удаленный);

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

  • Действие сброса или переназначения интерпретируется более универсальным образом:

  • любой вызов неконстантной функции в общем указателе может потенциально сбросить указатель;

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

Примеры

ненужная сложность интерфейса

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

ненужное осложнение интерфейса — упрощенное

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