第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么std :: shared_ptr <void>工作

為什么std :: shared_ptr <void>工作

C++
一只萌萌小番薯 2019-11-25 14:47:31
我發(fā)現(xiàn)一些代碼使用std :: shared_ptr在關(guān)機時執(zhí)行任意清理。起初,我認(rèn)為此代碼可能無法工作,但隨后嘗試了以下操作:#include <memory>#include <iostream>#include <vector>class test {public:  test() {    std::cout << "Test created" << std::endl;  }  ~test() {    std::cout << "Test destroyed" << std::endl;  }};int main() {  std::cout << "At begin of main.\ncreating std::vector<std::shared_ptr<void>>"             << std::endl;  std::vector<std::shared_ptr<void>> v;  {    std::cout << "Creating test" << std::endl;    v.push_back( std::shared_ptr<test>( new test() ) );    std::cout << "Leaving scope" << std::endl;  }  std::cout << "Leaving main" << std::endl;  return 0;}該程序給出輸出:At begin of main.creating std::vector<std::shared_ptr<void>>Creating testTest createdLeaving scopeLeaving mainTest destroyed我有一些關(guān)于為什么可行的想法,這與為G ++實現(xiàn)的std :: shared_ptrs的內(nèi)部有關(guān)。由于這些對象將內(nèi)部指針與計數(shù)器包裝在一起,因此從std::shared_ptr<test>到std::shared_ptr<void>的轉(zhuǎn)換可能不會妨礙析構(gòu)函數(shù)的調(diào)用。這個假設(shè)正確嗎?當(dāng)然還有一個更重要的問題:這是否可以保證按標(biāo)準(zhǔn)運行,或者可能進一步更改std :: shared_ptr的內(nèi)部結(jié)構(gòu),其他實現(xiàn)實際上會破壞此代碼嗎?
查看完整描述

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。


查看完整回答
反對 回復(fù) 2019-11-25
?
鳳凰求蠱

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é)點。


查看完整回答
反對 回復(fù) 2019-11-25
?
紫衣仙女

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


查看完整回答
反對 回復(fù) 2019-11-25
  • 3 回答
  • 0 關(guān)注
  • 1354 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號