type t (* void *)

ソフトウエアのこととか

C++: 返り値として自分自身を返すメソッドにshared_ptrを使う

#include <vector>
#include <memory>
#include <utility>

class A {
public:
    int x;
    A(int x) : x(x) {}

    std::shared_ptr<A> f() {
        return std::shared_ptr<A>(this);
    }
};

int main() {
    auto a = std::shared_ptr<A>(new A(123));
    auto v = std::vector<std::shared_ptr<A>>();
    v.push_back(a->f());
    v.push_back(a->f());
    return v.size();
}

*** Error in./a.out': free(): invalid pointer: 0x00007ffcc80eb1cc ***`という素敵なメッセージとともに異常終了する。

教えていただいた方法で試してみる。

#include <vector>
#include <memory>
#include <utility>

class A : public std::enable_shared_from_this<A> {
public:
    int x;
    A(int x) : x(x) {}

    std::shared_ptr<A> f() {
        return shared_from_this();
    }
};

int main() {
    auto a = std::make_shared<A>(A(123));
    auto v = std::vector<std::shared_ptr<A>>();

    v.push_back(a->f());
    v.push_back(a->f());
    return v.size();
}

これは正常に終了する。めでたしめでたし。 ただしこれ、必ずthisがshared_ptrにより管理されていなければならず、そうでない場合にはエラーが発生するっぽいのでなかなかこわい。 例えば上の例ならばmainの中にauto b = new A(256); b->f();という行があったならば、

terminate called after throwing an instance of 'std::bad_weak_ptr'
what():  bad_weak_ptr

といってしんでしまう。