青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Error

C++博客 首頁 新隨筆 聯系 聚合 管理
  217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks
首先一個原則是這樣:被用來delete的指針,一定是new出來的。
在設計智能指針的時候發現,如果采用delete this機制,到最后可能會有嚴重的問題。
假設有這樣的多重繼承:
class CA{};
class CB{};
class CC{};
class CABC : public CA, public CB, public CC
{};
CABC* pAbc = new CABC;
CA* pA = pAbc;
CB* pB = pAbc;
CC* pC = pAbc;
A B C指針的值都是不一樣的,如果是簡單的使用delete 來刪除,問題就大條了,pB pC的地址和new出來的pAbc不一樣,這樣就出現堆錯誤。
如果設計入侵式RefObj問題就大條了:
class Ref
{
public:
virtual void Test()
{
std::cout << this << std::endl;
}
int m_i;
};
class CA : public virtual Ref{};
class CB : public virtual Ref{};
class CC : public virtual Ref{};
class CABC : public CA, public CB, public CC{};
         C* pAbc = new CABC;
CA* pA = pAbc;
CB* pB = pAbc;
CC* pC = pAbc;
通過打印可以看到,雖然ABC 在基類Test打印出來的this地址一致,但是和實際正確的delete指針(new出來的)是不一致的,這就準備堆錯誤了,,,
這基本意味著使用入侵式樣Ref的類,使用了多重繼承就是作死。除非和com的思想一樣,Ref不是作為基類處理,而是作為純虛接口,但是又會使得編碼復雜化,基本上全部要用組合來替代繼承
class IXXX;
class CXXX;
class IYYY;
class CYYYXXX : public CXXX, public IYYY;
這樣的用法無法實現,應為沒有實現IXXX接口,是一個虛基類,實現了在調用的時候也是各種基類未指定的錯誤。

奇怪的是shared_ptr沒有這個限制,猜測是在第一次從裸指針構造出來的時候,保留了原始地址,生成了一個析構函數,會在shared_ptr之間共享,直到最后一個對象析構的時候調用.
實際觀察std::shared_ptr的實現,發現其構造函數不是控制一定要轉換成T指定的類型,而是給入參數的實際類型,后面的管理也分兩個部分,一層得到根據T轉換后的值,實際的生命周期管理得到仍然是實際類型,所以他delete的時候還是當初給定的值。
所以,感覺智能指針不是什么好東西,背后的細節太多,一個不小心就死翹翹



class RefObj
{
public:
RefObj() : m_i(0){}
public:
void Increate(){m_i++;}
void Decreate()
{
if(0 == --m_i)
{
delete this;
}
}
private: 
int m_i;
};
class BaseA : public virtual RefObj {public: int m_iA;};
class BaseB : public virtual RefObj {public: int m_iB;};
class BaseC : public virtual RefObj {public: int m_iC;};
class CBaseABC : public BaseA,
public BaseB,
public BaseC
{
};
void Test(BaseB* pB)
{
pB->Decreate();
}
int _tmain(int argc, _TCHAR* argv[])
{
ETcpSocket tcpSocket;
CBaseABC* pABC = new CBaseABC;
pABC->Increate();
BaseB* pB = pABC;
Test(pB);
return 0;
}



始終還是覺得相比shared_ptr,RefObj這種,還是有部分場景更加格式,至少不用擔心類型轉換變得異常麻煩,,,
后發現如下實現方式:
class IRefObj
{
public:
virtual void __DecRef() = 0;
};
template<typename TType>
class TRefObj : public IRefObj
{
public:
void __DecRef()
{
delete reinterpret_cast<TType*>(this);
}
};
class CRefTest : public TRefObj<CRefTest>
{
};
class CRefTestA : public CRefTest
{
};
class CTestA {int i;};
class CTestB {int j;};
class CTestC : public CTestB, public CRefTestA, public  CTestA
{
};
int _tmain(int argc, _TCHAR* argv[])
{
CTestC* pTC = new CTestC;
CTestB* pTB = pTC;
CRefTestA* pRTA = pTC;
CTestA* pTA = pTC;
pRTA->__DecRef();

這個時候CRefTest是預期額值,懷疑可能和編譯器有關,VS測試OK,gcc沒去實驗。
分析了一下原因:C++保證單根繼承的時候基類和派生類地址是一樣的,如果是多重繼承,那么也保證和最深的根父類地址樣,順便的,從最深的根節點,選一路下來是安全的。
class CRefTest : public TRefObj<CRefTest>所以約定TRefObj<CRefTest>這玩意和永遠和接口在一個級別,可以保證IRefObj永遠是最深的根,就安全了?
目前只在控件設計的時候用RefObj吧,,,坑的比較深,,,
posted on 2014-10-16 16:29 Enic 閱讀(781) 評論(2)  編輯 收藏 引用 所屬分類: C/C++技巧

評論

# re: C++多重繼承導致delete引起堆錯誤、智能指針設計陷阱[未登錄] 2014-10-17 10:58 Chipset
這種對象指針默認轉換中類型都丟了,析構的時候調用哪個系夠函數?手工刪除時就死悄悄,用智能指針當然也照樣死悄悄。何止對象這樣啊,C++里永遠都是這樣,如果自己想自殺,C++絕對成全你,這是Human Right!  回復  更多評論
  

# re: C++多重繼承導致delete引起堆錯誤、智能指針設計陷阱 2014-10-30 14:19 Enic
用boost::shared_ptr 或者std::shared_ptr的時候沒有這個問題,我猜測是共享數據卡里邊保留了原始指針,,,@Chipset
  回復  更多評論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩亚洲一区| 欧美成人中文| 国语精品中文字幕| 欧美日韩一区二区三区在线观看免 | 亚洲三级影院| 久久香蕉国产线看观看av| 欧美在线看片| 免费亚洲电影| 亚洲欧洲三级| 亚洲一区视频在线| 性高湖久久久久久久久| 久久精品免费播放| 欧美成人免费网站| 欧美日韩在线观看视频| 国产一二三精品| 亚洲国产精品一区二区www在线| 日韩午夜一区| 欧美一区二区三区啪啪| 欧美成人精品一区| 亚洲视频在线观看网站| 久久久综合香蕉尹人综合网| 欧美日本在线视频| 国产综合在线看| 中文一区在线| 欧美成人免费在线观看| 在线午夜精品| 久热re这里精品视频在线6| 欧美激情亚洲一区| 国产又爽又黄的激情精品视频 | 亚洲免费在线| 欧美一区二区三区免费观看视频| 免费欧美日韩| 国内精品免费在线观看| 国产精品99久久久久久久女警 | 亚洲欧美日韩国产一区二区三区| 午夜日韩av| 欧美gay视频| 一区二区三区色| 免播放器亚洲| 韩日成人在线| 亚洲欧美在线视频观看| 免费一级欧美片在线播放| 一本久久青青| 欧美国产精品v| 一区二区视频免费完整版观看| 一区二区三区鲁丝不卡| 欧美激情中文字幕一区二区| 在线视频欧美日韩精品| 欧美精品一区二| 亚洲欧洲一区二区在线观看| 久久久水蜜桃| 亚洲欧美日本另类| 国产精品福利av| 亚洲一区二区三区色| 亚洲激情在线播放| 欧美xxx在线观看| 亚洲第一视频网站| 男人插女人欧美| 久久久一本精品99久久精品66| 国产在线欧美日韩| 久久久久久久97| 久久久久一区二区三区| 精品不卡一区| 欧美激情小视频| 美女任你摸久久| 欧美jizzhd精品欧美巨大免费| 国产欧美视频一区二区三区| 午夜精品久久久久久久久久久久| 亚洲图片欧美午夜| 国产精品成人播放| 久久丁香综合五月国产三级网站| 亚洲综合精品一区二区| 国产午夜精品久久久久久久| 久久精品99国产精品日本| 亚洲欧美日韩在线| 国产自产女人91一区在线观看| 久久人人爽人人爽| 免费观看欧美在线视频的网站| 亚洲欧洲日韩女同| 亚洲精品久久久久久久久久久久久| 欧美精品午夜| 午夜精品偷拍| 久久久久久久久蜜桃| 亚洲激情在线观看| 亚洲精品中文字幕在线| 国产精品久久久久久久一区探花| 欧美在线视频日韩| 免费亚洲电影| 亚洲女优在线| 久久一区二区三区av| 99re6这里只有精品视频在线观看| 亚洲日本理论电影| 国产精品专区第二| 欧美大色视频| 国产精品久久久久91| 久久久久九九九九| 在线视频欧美日韩| 久久综合伊人77777| 欧美电影免费观看高清| 亚洲欧美精品在线观看| 亚洲欧美另类在线观看| 最近中文字幕日韩精品 | 国产性天天综合网| 你懂的亚洲视频| 国产精品三级视频| 欧美电影免费观看| 国产精品日韩一区| 亚洲国产日韩欧美在线99| 国产精品婷婷| 日韩网站在线观看| 在线日韩日本国产亚洲| 亚洲先锋成人| 9l国产精品久久久久麻豆| 久久精选视频| 欧美在线免费观看亚洲| 欧美激情在线狂野欧美精品| 久久精品国产在热久久 | 欧美大片在线观看一区二区| 亚洲综合视频网| 欧美成人精品h版在线观看| 性18欧美另类| 国产精品久久久久77777| 亚洲欧洲精品一区二区三区| 国产一区二区三区四区hd| av不卡在线| 日韩一级二级三级| 六月婷婷一区| 欧美1区免费| 黄色日韩在线| 午夜在线一区二区| 亚洲免费视频在线观看| 欧美日韩国产限制| 亚洲国产精品第一区二区三区| 国产精品色一区二区三区| 亚洲激情图片小说视频| 激情五月综合色婷婷一区二区| 欧美成人资源| 国产自产v一区二区三区c| 日韩西西人体444www| 免费不卡欧美自拍视频| 9久草视频在线视频精品| av成人黄色| 一本一本a久久| 亚洲综合三区| 国产欧美日韩视频一区二区三区| 在线视频你懂得一区| 午夜电影亚洲| 国产女主播一区| 香蕉久久夜色精品国产使用方法| 欧美怡红院视频| 国产亚洲一级高清| 欧美一区二区三区四区视频| 久久久精品国产免费观看同学| 国产在线观看91精品一区| 久久男女视频| 午夜精品偷拍| 亚洲精品资源美女情侣酒店| 亚洲人成在线免费观看| 蜜桃av噜噜一区| 亚洲另类在线一区| 亚洲性线免费观看视频成熟| 欧美日韩三区| 亚洲免费影视| 免费成人高清视频| 亚洲伦理网站| 国产乱子伦一区二区三区国色天香| 亚洲欧美日韩精品久久久久| 久久资源在线| 亚洲无人区一区| 韩国精品在线观看| 欧美激情一区二区三区蜜桃视频| 中文一区二区| 乱人伦精品视频在线观看| 9l国产精品久久久久麻豆| 国产精品永久免费在线| 欧美+日本+国产+在线a∨观看| 99精品视频免费在线观看| 久久久久**毛片大全| 99成人在线| 国语自产精品视频在线看一大j8 | 亚洲免费视频在线观看| 在线高清一区| 国产精品裸体一区二区三区| 久久久欧美一区二区| 一本久道久久综合婷婷鲸鱼| 久久一区二区精品| 亚洲一区亚洲二区| 亚洲国产导航| 国产亚洲欧美一区二区| 欧美日韩精品综合| 久久伊人免费视频| 亚洲愉拍自拍另类高清精品| 欧美成人午夜| 久久精品一二三| 亚洲一区二区三区在线| 亚洲欧洲一区| 亚洲福利视频网站| 国产精品视频专区| 欧美三级午夜理伦三级中文幕| 麻豆国产精品va在线观看不卡|