C++ Academy · レッスン

カスタムデリーターとmake関数

std::make_unique、std::make_shared、カスタムデリーターを、メモリ以外のリソースに活用します。

レッスン 4/413 ステップ

「カスタムデリーターとmake関数」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

カスタムデリータが必要な理由

すべてのリソースが deleteで解放されるわけではありません。ファイルハンドル、ソケット、OS固有のリソース、配列には、それぞれ異なるクリーンアップ関数が必要です。

unique_ptrのデフォルトデリータ

デフォルトでは unique_ptr<T>は deleteを使用します。配列には delete[]を呼び出す unique_ptr<T[]>を使用してください。

カスタムデリータの指定

2番目のテンプレート引数として呼び出し可能なオブジェクトを渡します。デリータは生ポインターを受け取り、適切に解放します。

auto closer = [](FILE* f) { if (f) std::fclose(f); };
std::unique_ptr<FILE, decltype(closer)> file(
    std::fopen("data.txt", "r"), closer);

shared_ptrのデリータ

shared_ptrはデリータを制御ブロックに格納します。型は型消去されるため、shared_ptr自体の型は変わりません。

std::shared_ptr<FILE> file(
    std::fopen("data.txt", "r"),
    [](FILE* f) { if (f) std::fclose(f); }
);

カスタムデリータの一般的な用途

実際の使用例:

  • Cライブラリのハンドル(FILE*、sqlite3*、curlハンドル)
  • OSリソース(WindowsのHANDLE、Unixのfd)
  • カスタムメモリプール
  • 外部オブジェクトの参照カウント管理

std::make_unique(C++14)

unique_ptrを作成する推奨方法です。引数をコンストラクターに転送し、生の newを避けられます。

auto p = std::make_unique<Widget>(arg1, arg2);

make_uniqueを使う理由

3つの利点があります:

  • 例外安全性 — ユーザーコードに生の newが不要
  • 型を2回記述する必要がない
  • 生ポインターを誤って2つの unique_ptrに渡すことがない

std::make_shared

shared_ptrの場合、make_sharedは制御ブロックとオブジェクトを1回のヒープ割り当てで確保します。個別に割り当てるより高速です。

auto p = std::make_shared<Widget>(arg1, arg2);

make_sharedに欠点がある場合

1回の割り当てで確保するため、すべての weak_ptrもなくなるまでオブジェクトのメモリが解放されません。weak_ptrが shared_ptrより長く存続する場合は、2段階で構築する方法を優先してください。

カスタムデリータとmakeの組み合わせ

make_uniqueと make_sharedはカスタムデリータを直接受け取れません。その場合はスマートポインターを手動で構築してください。

// make_shared cannot take a deleter
std::shared_ptr<FILE> file(
    std::fopen("data.txt", "r"),
    [](FILE* f) { if (f) std::fclose(f); }
);

落とし穴:ラムダの型をテンプレート引数に使う場合

各ラムダは固有の型を持ちます。unique_ptrでは、宣言時に decltype(my_deleter)を使用してください。または、型を単純に保つために名前付き関数や関数ポインターを使用してください。

確認問題

std::shared_ptrとその制御ブロックを1回のヒープ割り当てで確保できるファクトリ関数はどれですか?

まとめ

通常のケースでは make_uniqueと make_sharedを使用してください。リソースに delete以外の処理が必要な場合は、カスタムデリータ(ラムダまたは関数)を指定してください。対象にはファイルハンドル、OSオブジェクト、Cライブラリのクリーンアップなどがあります。

無料で開始

AI チューターと学ぶ C++ — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
51
レッスン
203

よくある質問

「カスタムデリーターとmake関数」レッスンは無料ですか?

はい。「カスタムデリーターとmake関数」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「カスタムデリーターとmake関数」で何を学びますか?

std::make_unique、std::make_shared、カスタムデリーターを、メモリ以外のリソースに活用します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「カスタムデリーターとmake関数」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. スマートポインターが生のnewとdeleteを置き換える理由
  2. unique_ptrによる単独所有
  3. shared_ptrとweak_ptrによる共有所有
  4. カスタムデリーターとmake関数
← C++ Academyに戻る