std::shared_ptr の基本動作

初期化、スコープによる解放、明示的解放の確認。

#include <memory>
#include <iostream>

class ToBeShared {
 public:
    ToBeShared() { std::cout << "ToBeShared Constructed. this="
                    << std::hex << this << std::endl; }
    ~ToBeShared() {std::cout << "ToBeShared Destructed. this="
                    << std::hex << this << std::endl; }
 };

int main() {
    auto printone = [](const std::string& name,
                       const std::shared_ptr<ToBeShared>& sp) {
        std::cout << name << "(" << std::hex << sp.get()
        << std::dec << ").use_count()= " << sp.use_count()
        << std::endl;
    };

    std::cout << "Creation" << std::endl;
    auto sp1 = std::make_shared<ToBeShared>();
    printone("sp1[make_shared]", sp1);
    auto sp2 = sp1;
    printone("sp2[copied sp1]", sp2);
    {   std::shared_ptr<ToBeShared> sp3;
        printone("sp3[defined]", sp3);
        sp3 = sp2;
        printone("sp3[copied sp2]", sp3);
    }  // = implicit delete
    std::cout << "sp3 out of scope." << std::endl;

    printone("sp2[before reset]", sp2);
    sp2.reset();  // = explicit delete

    printone("sp1[before reset]", sp1);
    sp1.reset();  // = explicit delete

    return 0;
}

実行結果。

Creation
ToBeShared Constructed. this=0x294f1eb03a0
sp1[make_shared](0x294f1eb03a0).use_count()= 1
sp2[copied sp1](0x294f1eb03a0).use_count()= 2
sp3[defined](0).use_count()= 0
sp3[copied sp2](0x294f1eb03a0).use_count()= 3
sp3 out of scope.
sp2[before reset](0x294f1eb03a0).use_count()= 2
sp1[before reset](0x294f1eb03a0).use_count()= 1
ToBeShared Destructed. this=0x294f1eb03a0

std::function の使い方

備忘録を兼ねて、こんな風に使うんだよというサンプルなど。
クラスのメンバ関数の場合(func1,func2)、
素の関数の場合(func3,func4)、
ラムダ関数を使う場合(func5,func6)。
それぞれ引数なし、ありの時の書き方。

#include <functional>
#include <iostream>

class class1 {
 public:
    void func1() { std::cout << "class1::func1()" << std::endl; }
    void func2(int i1, int i2) { std::cout << "class1::func2(" << i1 << "," << i2 << ")" << std::endl;  }
};

class class2 {
 public:
    std::function<void()> function1;
    std::function<void(int,int)> function2;

    std::function<void()> function3;
    std::function<void(int,int)> function4;

    std::function<void()> function5;
    std::function<void(int,int)> function6;
};

void func3() {
    std::cout << "func3()" << std::endl;
}

void func4(int i1, int i2) { std::cout << "func4(" << i1 << "," << i2 << ")" << std::endl; }

int main() {
    class1 c1;
    class2 c2;

    c2.function1 = std::bind(&class1::func1, &c1);
    c2.function2 = std::bind(&class1::func2, &c1, std::placeholders::_1, std::placeholders::_2);

    c2.function3 = std::function<void()>(func3);
    c2.function4 = std::bind(func4,std::placeholders::_1, std::placeholders::_2);

    c2.function5 = [&]() { std::cout << "lambda func5()" << std::endl; };
    c2.function6 = [&](int i1, int i2) { std::cout << "lambda func6(" << i1 << "," << i2 << ")" << std::endl; };

    c2.function1();
    c2.function2(3, 4);

    c2.function3();
    c2.function4(5, 6);

    c2.function5();
    c2.function6(7, 8);

    return 0;
}

実行結果。

class1::func1()
class1::func2(3,4)
func3()
func4(5,6)
lambda func5()
lambda func6(7,8)