アルパカ三銃士

〜アルパカに酔いしれる獣たちへ捧げる〜

vector とは生のポインタではなく unique_ptr を使う

前回以下のような記事を書いた。

codehex.hateblo.jp

これの解決策 + エクセレントなコードを見つけたため記録を残しておく。

解決策としては unique_ptrvector を作成してあげること。非常に簡単。ただ、c++14 を指定してコンパイルしてあげないと辛い問題があって、それは生のポインタから unique_ptr を作成するためのやり取りを std::make_unique<T>() という関数を使うからである。

例えば今まで以下のように vector へデータを突っ込んでいたとする。

T *a = some_get();
vector.push_back(a);

これを unique_ptr を使って書き直せば次のようになる。

T *a = some_get();
vector.push_back(std::move(std::make_unique<T>(a)));

std::move#include <memory> を指定すると使えるようになる。
こうすることで、ある時点で vector が再アロケートを行っても保存していたデータが破壊されずに、正しく扱うことができた。
しかし、この書き方は冗長になってくる。

どうやって検索をしたのか分からないが、ベストプラクティスっぽいコードを見つけた。

github.com

上記のコードで例えると T がクラスであった場合、次のようなメソッドを持たせておくことで、実体の場合や生のポインタの状態でもいい感じに unique_ptr を作成することが可能である。

class T {
    ...
    inline std::unique_ptr<T> clone() {
        return std::make_unique<T>(*this);
    }
};

T *a = some_get();
T b = some_get();
a->clone();
b.clone();