3 回答

TA貢獻1777條經(jīng)驗 獲得超10個贊
訣竅是std::shared_ptr執(zhí)行類型擦除?;旧希瑂hared_ptr創(chuàng)建新deleter函數(shù)時,它將在內(nèi)部存儲一個函數(shù)(可以將其作為構(gòu)造函數(shù)的參數(shù)提供,但如果不存在,則默認(rèn)為call delete)。當(dāng)shared_ptr銷毀時,它將調(diào)用該存儲的函數(shù),然后將調(diào)用deleter。
可以使用std :: function簡化類型擦除的簡單草圖,并避免所有引用計數(shù)和其他問題在此處顯示:
template <typename T>
void delete_deleter( void * p ) {
delete static_cast<T*>(p);
}
template <typename T>
class my_unique_ptr {
std::function< void (void*) > deleter;
T * p;
template <typename U>
my_unique_ptr( U * p, std::function< void(void*) > deleter = &delete_deleter<U> )
: p(p), deleter(deleter)
{}
~my_unique_ptr() {
deleter( p );
}
};
int main() {
my_unique_ptr<void> p( new double ); // deleter == &delete_deleter<double>
}
// ~my_unique_ptr calls delete_deleter<double>(p)
當(dāng)shared_ptr從另一個復(fù)制(或默認(rèn)構(gòu)造)一個a時,刪除器會被傳遞,因此當(dāng)您shared_ptr<T>從構(gòu)造a 時shared_ptr<U>,有關(guān)要調(diào)用的析構(gòu)函數(shù)的信息也會被傳遞deleter。

TA貢獻1825條經(jīng)驗 獲得超4個贊
shared_ptr<T> 邏輯上[*]具有(至少)兩個相關(guān)的數(shù)據(jù)成員:
指向被管理對象的指針
指向?qū)⒂糜阡N毀它的刪除函數(shù)的指針。
您的刪除器功能shared_ptr<Test>給你構(gòu)建的方式,是正常的一個Test,該指針轉(zhuǎn)換為Test*和delete這樣。
當(dāng)您將推shared_ptr<Test>入的向量時,盡管第一個轉(zhuǎn)換為shared_ptr<void>,這兩個都將被復(fù)制void*。
因此,當(dāng)向量元素在使用最后一個引用被破壞時,它將指針傳遞給正確刪除它的刪除器。
實際上,這要復(fù)雜一些,因為shared_ptr可以使用刪除器函子而不是函數(shù),因此甚至可能存儲每個對象的數(shù)據(jù),而不僅僅是函數(shù)指針。但是對于這種情況,沒有這樣的額外數(shù)據(jù),僅存儲指向模板函數(shù)實例化的指針就足夠了,該模板參數(shù)具有捕獲必須刪除指針的類型的模板參數(shù)。
[*]從邏輯上講,它可以訪問它們-它們可能不是shared_ptr本身的成員,而是它指向的某些管理節(jié)點。

TA貢獻1839條經(jīng)驗 獲得超15個贊
shared_ptr<T>(Y *p)實際上,構(gòu)造函數(shù)似乎正在調(diào)用shared_ptr<T>(Y *p, D d)where d是為對象自動生成的刪除器。
發(fā)生這種情況時,對象的類型Y是已知的,因此該shared_ptr對象的刪除器知道要調(diào)用哪個析構(gòu)函數(shù),并且當(dāng)指針存儲在向量中時,此信息也不會丟失shared_ptr<void>。
的確,規(guī)范要求接收shared_ptr<T>對象接受shared_ptr<U>對象必須為true并且U*必須隱式轉(zhuǎn)換為a T*,這確實是這種情況,T=void因為任何指針都可以void*隱式轉(zhuǎn)換為指針。沒有任何關(guān)于刪除器的說明,因為刪除器將是無效的,因此確實規(guī)范要求它可以正常工作。
從技術(shù)上講,IIRC a shared_ptr<T>包含指向包含參考計數(shù)器的隱藏對象的指針和指向?qū)嶋H對象的指針;通過將刪除器存儲在此隱藏結(jié)構(gòu)中,可以使此看似魔術(shù)的功能正常工作,同時仍保持shared_ptr<T>與常規(guī)指針一樣大的大?。ǖ牵∠弥羔樞枰p重定向)
shared_ptr -> hidden_refcounted_object -> real_object
- 3 回答
- 0 關(guān)注
- 1354 瀏覽
添加回答
舉報