警告 C26415

智能指针参数仅用于访问包含的指针。 请改用 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);
    // ...
}