鍍金池/ 問答/C  C++/ 關(guān)于 c++的智能指針析構(gòu)2次的問題

關(guān)于 c++的智能指針析構(gòu)2次的問題

我正在學(xué)習(xí)c++的智能指針這一塊??戳撕芏嗵樱瑩?jù)說這樣的程序會(huì)引起2次析構(gòu)對(duì)象。但是我這里程序運(yùn)行一切正常。這個(gè)怎么解釋?謝謝大家!(系統(tǒng):centos 7, g++版本:4.8.5)
clipboard.png

clipboard.png

回答
編輯回答
陌如玉

槽點(diǎn)1:

BaseClass *b = new BaseClass();
std::shared_ptr<BaseClass> test(b->getInstance());

這是bad practice, 雖然還不是UB, 但是只有一步之遙了, 比如加一個(gè)std::shared_ptr<BaseClass> test2(b->getInstance());double delete了.

解決方法:

所以第一步要做的是把BaseClass *b = new BaseClass();修改成std::shared_ptr<BaseClass> b(new BaseClass);

到此結(jié)束了嗎? 不, 繼續(xù)噗:

槽點(diǎn)2:

  std::shared_ptr<BaseClass> getInstance()
  {
      return std::shared_ptr<BaseClass>(this);
  }
  

假設(shè)已經(jīng)做出上述修改了, 由于上段代碼的存在, 依舊會(huì)杯具. 原因和上面類似, 因?yàn)?code>test并不知道this已經(jīng)被b用過了, 所以引用計(jì)數(shù)就gg了. 你需要自己實(shí)現(xiàn)一個(gè)shared_ptr就能理解了.

解決方法:

使用std::enable_shared_from_this:

class BaseClass :  enable_shared_from_this<S>
{
public:
  BaseClass(){cout << "BaseClass construct" << endl;}
  ~BaseClass(){cout << "Base destructor" << endl;}
  std::shared_ptr<BaseClass> getInstance()
  {
      return shared_from_this();
  }
};

想進(jìn)一步了解可以去看enable_shared_from_this是如何實(shí)現(xiàn)的.

槽點(diǎn)3:

不存在disconstruct這種說法, 跟我念: destructor

槽點(diǎn)4:

永遠(yuǎn)不要貼截圖(qq群里也一樣, 不通過markdown就用paste.ubuntu.

懶得打字這次我給你輸好了, 請(qǐng)貼近問題描述中:

#include <iostream>
#include <memory>
using namespace std;
class BaseClass;
class ChildClass;
typedef std::shared_ptr<BaseClass> BaseClassPtr;
typedef std::shared_ptr<ChildClass> ChildClassPtr;
class BaseClass
{
public:
  BaseClass(){cout << "BaseClass construct" << endl;}
  ~BaseClass(){cout << "Base destructor" << endl;}
  std::shared_ptr<BaseClass> getInstance()
  {
      return std::shared_ptr<BaseClass>(this);
  }
};
int main()
{
    BaseClass *b = new BaseClass();
    std::shared_ptr<BaseClass> test(b->getInstance());
    cout << "end" << endl;
}

槽點(diǎn)5:

你應(yīng)該把這段代碼的鏈接發(fā)出來, 一方面展示自己從哪里獲取的信息, 一方面挺想看是誰(shuí)寫出這樣的代碼的.

槽點(diǎn)6:

這是針對(duì)另一位答主的, 語(yǔ)言沒有規(guī)定是heap, 只說了是free store. 具體可以參見帝球此貼

槽點(diǎn)7:

這是一個(gè)c++的問題, 不要貼c的標(biāo)簽, 完全兩門不搭界的語(yǔ)言.

2017年6月24日 09:14
編輯回答
空痕

那是因?yàn)槟?em>最后沒有delete b這個(gè)指針. 在 堆(heap) 中分配的內(nèi)存指針需要delete, 否則可能會(huì)造成內(nèi)存泄漏.
智能指針會(huì)自動(dòng)釋放該對(duì)象的指針. 所以再次 delete 會(huì)銷毀兩次.
所以,不要混用智能指針和普通指針.

2018年1月5日 16:14