2013-09-21 108 views
1

我想在接受void *的C函數中傳遞shared_ptr。 shared_ptr中創建的對象是否會被銷燬以及何時可以銷燬?像,在回調中將shared_ptr轉換爲void *

class CBar 
{ 
public: 
    CBar(){} 
    ~CBar(){} 
    void lock(){} 
    void unlock(){} 
}; 

//---------------------------------------------------- 

typedef struct element 
{ 
    std::string filename; 
    void (*cb)(std::string filename, void* data); 
    void* data; 
}; 

std::list<element> elm; 

void reg(std::string filename, void (*cb)(std::string filename, void*data), void* data) 
{ 
    element item; 
    item.filename = filename; 
    item.cb = cb; 
    item.data = data; 
} 

void unreg(std::string filename) 
{ 
    std::list<elements>::iter; 
    for(iter=elm.begin();iter!=elm.end();++iter) 
    { 
     if((*iter).filename == filename) 
     { 
     elm.erase(iter); 
     break; 
     } 
    } 
} 

void exec() 
{ 
    std::list<element>::iterator iter; 
    for(iter=elm.begin();iter!=elm.end();++iter) 
    { 
     (*iter).cb((*iter).filename,(*iter).data); 
    } 
} 

//--------------------------------------------------- 
// in another source file 

void cb(std::string filename, void* data) 
{ 
    boost::shared_ptr<CBar> cbar = *(boost::shared_ptr<CBar>*)(data); 
    cbar->lock(); 
} 

void foo(std::string filename) 
{ 
    //create the shared_ptr here. 
    boost::shared_ptr<CBar> ffoo(new CBar); 

    //then pass the shared_ptr object 
    reg(filename, &cb, &ffoo); 

} 

int main() 
{ 
    foo("file"); 
    exec(); 

    return 0; 
} 
+0

那麼如何以及何時可以銷燬? – domlao

+0

'typedef struct element'甚至合法嗎?你沒有鍵入任何東西。 –

回答

1

當你的函數離開作用域時,共享指針將被銷燬。如果它是包裝數據的最後一個,那麼數據會隨之一起傳輸(因此列表中的存儲也會變成虛假)。你的樣本會更差,因爲你發送的是局部變量的地址,在reg()函數退出並且局部變量超出範圍的時刻,這將是完全未定義的行爲。

我建議你放一個共享指針在你的元素結構中也是如此。畢竟,它是共享的,因此它將延長數據的壽命,直到元素被刪除。如果這是一個真正的C型回調,您可能還需要製作第一個回調參數a const char*並相應地發送c_str()方法。

注:我沒有安裝升壓,所以下面的代碼使用std::shared_ptr<>,但語義應該是相同的。

#include <iostream> 
#include <vector> 
#include <string> 
#include <list> 
#include <memory> 
#include <cstdlib> 

class CBar 
{ 
public: 
    CBar(){} 
    ~CBar(){} 
    void lock(){} 
    void unlock(){} 
}; 

struct element 
{ 
    std::string filename; 
    void (*cb)(std::string, void* data); 
    std::shared_ptr<CBar> data; 
}; 


std::list<element> elm; 

void reg(std::string filename, 
     void (*cb)(std::string, void*), 
     std::shared_ptr<CBar>& data) 
{ 
    element item; 
    item.filename = filename; 
    item.cb = cb; 
    item.data = data; 
    elm.push_back(item); 
} 

void exec() 
{ 
    std::list<element>::iterator iter; 
    for(iter=elm.begin();iter!=elm.end();++iter) 
    { 
     iter->cb(iter->filename, iter->data.get()); 
    } 
} 

// in another source file 
void cb(std::string filename, void* data) 
{ 
    CBar *cbar = static_cast<CBar*>(data); 
    cbar->lock(); 
} 

void foo(std::string filename) 
{ 
    //create the shared_ptr here. 
    std::shared_ptr<CBar> ffoo(new CBar); 

    //then pass the shared_ptr object 
    reg(filename, &cb, ffoo); 

} 

int main() 
{ 
    foo("file"); 
    exec(); 
    return 0; 
} 
相關問題