警告 C26415
スマート ポインター パラメーターは、包含ポインターにアクセスするためにのみ使用されます。 代わりに T* または T& を使用してください。
C++ Core Guidelines: 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);
// ...
}