星期三, 6月 03, 2009

出錯

#include <iostream>
#include <boost/shared_ptr.hpp>

class TestA;

void printTestA(TestA* a){
std::cout << a << std::endl;
}

void printTestA(boost::shared_ptr<TestA> a){
std::cout << a << std::endl;
}

class TestA{
public:
TestA():x(0){}
void test(){
printTestA(this);
printTestA(boost::shared_ptr<TestA>(this));
}
private:
int x;
};


int main(){
boost::shared_ptr<TestA> x(new TestA());
x->test();
std::cout << x.get() << std::endl;
}

這樣子的程式碼會出錯,正在想怎麼解決 XD
好像有解,下午來菸酒菸酒~


---


這個問題其實是 boost::shared_ptr 遇到 this 會發生什麼有趣的事 XD
大鳥 在 comments 中解釋了為什麼會錯,感謝他(感覺比自己寫的還清楚,我就不重寫了 XD) fr3@K 有提到 enable_shared_from_this 是最佳解

對我而言,我利用這個機會好好看了一下 Boost smart ptr,看完才發現,離自己夢想中的 memory management ,還是有一段距離,這個問題在 mailing list 有人討論,也有人提出解法,官方建議兩種解法,一種是加入 weak_ptr,在建立此 object 時,利用 weak_ptr 指向自己,另外一種是 fr3@K 提的,其實這兩種方法殊途同歸,只是後面有包裝,當然,就我自己而言,我實在是不想為了解決這個問題再繼承一個 XD,但是自己寫也沒有多好。

這個 library 的邏輯我猜想是如此,要嘛你就全用(使用 boost::make_shared<T> 建立更好),使用 shared_ptr<T> ...etc 來管理,然後從頭用到尾,weak_ptr 就會出現在這種時候(在我下筆的此刻,雖然我知道它的用法與目的,但是還是不知道使用時機為何),如果想要在 C++ 使用懶人的方法來用記憶體,我們必需更努力的學會這個 library XD,身為一個學生,不太知道外面世界怎麼樣,只能說,盡量學習嘍 XD


補充一下修改後的程式碼:
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>

class TestA;

void printTestA(TestA* a){
std::cout << a << std::endl;
}

void printTestA(boost::shared_ptr<TestA> a){
std::cout << a << std::endl;
}

class TestA{
public:
//TestA():x(0){}
void test(){
printTestA(this);
printTestA(boost::shared_ptr<TestA>(weak_this));
}

static boost::shared_ptr<TestA> create(){
boost::shared_ptr<TestA> u = boost::make_shared<TestA>();
u->weak_this = u;
return u;
}
private:
int x;
boost::weak_ptr<TestA> weak_this;
};


int main(){
boost::shared_ptr<TestA> x = TestA::create();

x->test();
std::cout << x.get() << std::endl;
}

4 則留言:

Mr. BigCat 提到...

不知道有沒有錯 目測debug

printTestA(boost::shared_ptr<TestA>(this));

boost smart pointer應該是reference-count based
你這樣會產生一個臨時的shared_ptr
然後解構, reference count=0, delete原本的raw pointer
然後原本那個smart pointer就掛了

yen3 提到...

是啊,所以要想辦法讓這兩個使用相同的 reference count XD

fr3@K 提到...

enable_shared_from_this

yen3 提到...

@ fr3@K: 謝謝你的建議,寫在內容哩 !