メモ:スマートポインタ

#include <iostream>
#include <memory>
#include <tr1/memory>
#include <string>
#include <tr1/tuple>
using namespace std;
using namespace std::tr1;

class Item {
private:
    string value_;
public:
    Item( const char* v="???") : value_(v) {
        cout << "create Item(" << value_ << ")" << endl;
    }
    ~Item() {
        cout << "delete Item(" << value_ << ")" << endl;
    }
    string value() const { return value_; }
};

typedef auto_ptr<Item>      auto_item;
typedef shared_ptr<Item>    shared_item;
typedef weak_ptr<Item>      weak_item;


void func( auto_item item) {
    cout << "item points to " << (item.get() ? item->value() : "(null)") << endl;
}
auto_item 
ret_func( auto_item item ){
    cout << "item points to " << (item.get() ? item->value() : "(null)") << endl;
    return item;
}

void test_auto_ptr(){
    cout << "# test auto_ptr" << endl;
    auto_item p1(new Item("One"));
    auto_item p2(new Item("Two"));
    // p1の所有権をfuncの引数に渡す
    func( p1 );
    cout << "end func" << endl;
    // 渡されて参照がなくなったので、削除。
    p1 = p2;
    // p2の所有権をp1に委譲。
    cout << "p1 points to " << (p1.get() ? p1->value() : "(null)") << endl;
    cout << "p2 points to " << (p2.get() ? p2->value() : "(null)") << endl;
    // p2の中身がなくなる
    // p1の所有権をret_funcの引数に渡して、再度p1に戻す、
    p1 = ret_func( p1 );
    cout << "end ret_func" << endl;
}
//ここでp1削除


void func2( shared_item item) {
    cout << "item points to " << (item.get() ? item->value() : "(null)") << endl;
}
shared_item 
ret_func2( shared_item item ){
    cout << "item points to " << (item.get() ? item->value() : "(null)") << endl;
    return item;
}

void test_shared_ptr(){
    cout << "# test shared_ptr" << endl;
    shared_item p1( new Item("one") );
    shared_item p2( new Item("two") );
    {
        shared_item p3 = p1;
        cout << "p3 points to " << (p3.get() ? p3->value() : "(null)") << endl;
    }
    p1 = p2;
    func2(p2);
    cout << "end func2" << endl;
    p2 = ret_func2(p2);
    cout << "end ret_func2" << endl;

}

int main(void){

    test_auto_ptr();
    test_shared_ptr();

    return 1;
}