警告 C26417
共有ポインター パラメーターは参照渡しされ、リセットまたは再割り当ては行われません。 代わりに T* または T& を使用してください。
C++ Core Guidelines: R.35: shared_ptr<widget>& パラメーターを使用して、関数が共有ポインターを再シードする可能性があることを表します
参照による共有ポインターの受け渡しは、呼び出されたコードがスマート ポインター オブジェクトのターゲットを更新し、呼び出し元がこのような更新を表示することを期待するシナリオで役立つ場合があります。 共有ポインターを渡すための負担を軽減するためだけに参照を使用するのはよくありません。 呼び出されたコードがターゲット オブジェクトにのみアクセスし、その有効期間を管理しない場合は、リソース管理の詳細を公開するのではなく、生のポインターまたは参照を渡す方が安全です。
解説
このチェックは、共有ポインターのように動作する可能性が高いユーザー定義型を認識
std::shared_pointer
します。 ユーザー定義の共有ポインターには、次の特徴が必要です。オーバーロードされた逆参照またはメンバー アクセス演算子 (パブリックおよび非削除)
コピー コンストラクターまたはコピー代入演算子 (public および non-deleted);
削除されても既定化されてもいないパブリック デストラクター。 空のデストラクターは、従来通り、ユーザー定義としてカウントされます。
リセットまたは再割り当てのアクションは、より汎用的な仕方で解釈されます。
共有ポインターに対する非定数関数の呼び出しは、ポインターをリセットする可能性があります。
非定数共有ポインターへの参照を受け入れる関数の呼び出しは、そのポインターをリセットまたは再割り当てする可能性があります。
例
不必要に複雑なインターフェイス
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());
// ...
}