C++ primer摘要(11)---拷貝控制

拷貝控制

  • 當(dāng)定義一個類時讲衫,我們顯式或隱式的指定在此類型的對象拷貝寒随、移動、賦值和銷毀時做什么,一個類通過定義五種特殊的成員函數(shù)來控制這些操作
- [x] `拷貝構(gòu)造函數(shù)`
- [x] `拷貝賦值運(yùn)算符`
- [x] `移動構(gòu)造函數(shù)`
- [x] `移動賦值運(yùn)算符`
- [x] `析構(gòu)函數(shù)`
- [x] 拷貝和移動構(gòu)造函數(shù)定義了當(dāng)用同類型的另一個對象初始化本對象時做什么
- [x] 拷貝和移動賦值運(yùn)算符定義了將一個對象賦予同類型的另一個對象時做什么
- [x] 析構(gòu)函數(shù)定義了當(dāng)此類型對象銷毀時做什么
- [x] 上述這些操作統(tǒng)稱為`拷貝控制操作`
  • 如果一個類沒有定義上述這些拷貝控制成員顽悼,編譯器會自動為它定義缺失的操作,但對一些類來說几迄,依賴這些操作的默認(rèn)定義會導(dǎo)致災(zāi)難

拷貝蔚龙、賦值與銷毀

拷貝構(gòu)造函數(shù)
  • 如果一個構(gòu)造函數(shù)的第一個參數(shù)是自身類類型的引用,且任何額外參數(shù)都有默認(rèn)值映胁,則此構(gòu)造函數(shù)為拷貝構(gòu)造函數(shù)
class Foo{
    public:
        Foo();          //默認(rèn)構(gòu)造函數(shù)
        Foo(const Foo&);//拷貝構(gòu)造函數(shù)
        //......
}
  • 拷貝構(gòu)造函數(shù)的第一個參數(shù)必須是一個引用類型
  • 當(dāng)我們使用拷貝初始化時木羹,我們要求編譯器將右側(cè)運(yùn)算對象拷貝到正在創(chuàng)建的對象中,如果需要的話還要進(jìn)行類型轉(zhuǎn)換
  • 拷貝初始化是依靠拷貝構(gòu)造函數(shù)或移動構(gòu)造函數(shù)完成的
  • 拷貝初始化在下列情況會發(fā)生
- [x] 用`=`定義變量時發(fā)生
- [x] 將一個對象作為實(shí)參傳遞給一個非引用類型的形參
- [x] 從一個返回類型為非引用類型的函數(shù)返回一個對象
- [x] 用或括號列表初始化一個數(shù)組中的元素或一個聚合類中的成員
  • 拷貝構(gòu)造函數(shù)自己的參數(shù)必須類型
拷貝賦值運(yùn)算符
  • 與類控制其對象如何初始化一樣解孙,類也可以控制器對象如何賦值
Sales_data trans,accum;
trans = accum;  //使用Sales_data的拷貝賦值運(yùn)算符
  • 與拷貝構(gòu)造函數(shù)一樣坑填,如果類未定義自己的拷貝賦值運(yùn)算符抛人,編譯器會為它合成一個
  • 如果一個運(yùn)算符是一個成員函數(shù),則其左側(cè)的運(yùn)算對象就綁定到隱式的this指針參數(shù)
  • 賦值運(yùn)算符通常應(yīng)該返回一個指向其左側(cè)運(yùn)算對象的引用
  • 標(biāo)準(zhǔn)庫通常要求保存在容器中的類型具有賦值運(yùn)算符
析構(gòu)函數(shù)
  • 析構(gòu)函數(shù)執(zhí)行與構(gòu)造函數(shù)相反的操作
- [x] 構(gòu)造函數(shù)初始化對象的非static數(shù)據(jù)成員脐瑰,還可能做一些其他工作
- [x] 析構(gòu)函數(shù)釋放對象使用的資源妖枚,并銷毀對象的非static數(shù)據(jù)成員
  • 析構(gòu)函數(shù)沒有返回值,也不接受參數(shù)
  • 由于析構(gòu)函數(shù)不接受參數(shù)蚪黑,因此它不能被重載盅惜,對于一個給定類,只會有唯一一個析構(gòu)函數(shù)
  • 在一個構(gòu)造函數(shù)中忌穿,成員的初始化是在函數(shù)體執(zhí)行之前完成的抒寂,且按照它們在類中出現(xiàn)的順序進(jìn)行初始化
  • 在一個析構(gòu)函數(shù)中,首先執(zhí)行函數(shù)體掠剑,然后銷毀成員屈芜,成員按初始化的逆序進(jìn)行銷毀
  • 隱式銷毀一個內(nèi)置指針類型的成員不會delete它所指向的對象
  • 與普通指針不同,智能指針是類類型朴译,所以具有析構(gòu)函數(shù)井佑,因此,與普通指針不同眠寿,智能指針成員在析構(gòu)階段會自動銷毀
  • 什么時候會調(diào)用析構(gòu)函數(shù)(無論何時一個對象被銷毀躬翁,都會自動調(diào)用其析構(gòu)函數(shù))
- [x] 變量離開其作用域時被銷毀
- [x] 當(dāng)一個對象被銷毀時,其成員被銷毀
- [x] 容器(無論是標(biāo)準(zhǔn)庫容器還是數(shù)組)被銷毀時盯拱,其元素被銷毀
- [x] 對于動態(tài)分配的對象盒发,當(dāng)對指向它的指針應(yīng)用delete運(yùn)算符時被銷毀
- [x] 對于臨時對象,當(dāng)創(chuàng)建它的完整表達(dá)式結(jié)束時銷毀
  • 析構(gòu)函數(shù)自動運(yùn)行狡逢,所以我們的程序可以按需要分配資源宁舰,無需擔(dān)心何時釋放這些資源
  • 當(dāng)指向一個對象的引用或指針離開作用域時,析構(gòu)函數(shù)不會執(zhí)行
  • 當(dāng)一個類未定義自己的析構(gòu)函數(shù)時奢浑,編譯器會為它定義一個合成析構(gòu)函數(shù)蛮艰,類似拷貝構(gòu)造函數(shù)和拷貝賦值運(yùn)算符
  • 析構(gòu)函數(shù)體自身并不直接銷毀成員,成員是在析構(gòu)函數(shù)體之后隱含的析構(gòu)階段被銷毀的雀彼,在整個對象銷毀過程中壤蚜,析構(gòu)函數(shù)整體是作為成員銷毀步驟之外的另一部分而進(jìn)行的
三/五法則
  • 如果一個類需要一個析構(gòu)函數(shù),那么它幾乎可以肯定也需要一個拷貝構(gòu)造函數(shù)和一個拷貝賦值運(yùn)算符
  • 如果一個類需要一個拷貝構(gòu)造函數(shù)详羡,幾乎可以肯定它也需要一個拷貝賦值運(yùn)算符仍律,反之亦然
  • 無論是需要拷貝構(gòu)造函數(shù)還是需要拷貝賦值運(yùn)算符都不洗染意味著需要析構(gòu)函數(shù)
使用=default
  • 我們可以通過拷貝控制成員定義=default來顯式的要求編譯器生成合成版本
class Sales_data{
public:
    //拷貝控制成員;使用default
    Sales_data() = default;
    Sales_data(const Sales_data&) = default;
    Sales_data operator=(const Sales_data &);
    ~Sales_data()=default;
    //其余成員定義如前
}
  • 我們只能對具有合成版本的成員函數(shù)使用=default(即实柠,默認(rèn)構(gòu)造函數(shù)或拷貝控制成員)
阻止拷貝
  • 大多數(shù)類應(yīng)該定義默認(rèn)構(gòu)造函數(shù)水泉、拷貝構(gòu)造函數(shù)和拷貝賦值運(yùn)算符,無論是隱式的還是顯式的
  • 當(dāng)一個類明確不允許拷貝賦值操作時,必須使用=delete將拷貝構(gòu)造函數(shù)與拷貝賦值運(yùn)算符定義為刪除的,顯式的阻止該函數(shù)被編譯器默認(rèn)生成草则,如iostream類
  • 通過=delete可以將拷貝構(gòu)造函數(shù)和拷貝賦值運(yùn)算符定義為刪除的函數(shù)來阻止拷貝钢拧,刪除的函數(shù)是這樣一種函數(shù):我們雖然聲明了它們,但不能以任何方式使用炕横,在函數(shù)的參數(shù)列表后面加上=delete來指出我們希望將它定義為刪除的
struct NoCopy{
    NoCopy() = default;     //使用合成的默認(rèn)構(gòu)造函數(shù)
    NoCopy(const NoCopy&) = delete; //阻止拷貝
    NoCopy & operator=(const NoCopy&) = delete; //阻止賦值
};
  • =delete通知編譯器源内,我們不希望定義這些成員
  • =delete必須出現(xiàn)在函數(shù)第一次聲明的時候
  • 我們可以對任何函數(shù)指定=delete,但只能對編譯器可以合成默認(rèn)函數(shù)的默認(rèn)構(gòu)造函數(shù)或拷貝控制成員使用=default
  • 雖然刪除函數(shù)的主要用途是禁止拷貝控制成員份殿,但當(dāng)我們希望引導(dǎo)函數(shù)匹配過程時膜钓,刪除函數(shù)有時也是有用的
  • 需要注意的是,我們不能刪除析構(gòu)函數(shù)卿嘲,如果析構(gòu)函數(shù)被刪除颂斜,我們不能定義該類的變量或臨時對象(編譯器不允許)
  • 對于刪除了析構(gòu)函數(shù)的類型,雖然我們不能定義這種類型的變量或成員拾枣,但可以動態(tài)分配這種類型的對象沃疮,但是不能釋放這些對象
struct NoDtor{
    NoDtor() = default;
    ~NoDtor() = delete;
};

NoDtor nd;  //錯誤,析構(gòu)函數(shù)刪除不能定義變量
NoDtor * p = new NoDtor(); //正確梅肤,但不能delete
delete p;   //錯誤司蔬,析構(gòu)函數(shù)是刪除的
  • 對于析構(gòu)函數(shù)已刪除出的類型,不能定義該類型的變量或釋放指向該類型動態(tài)分配對象的指針
  • 在新標(biāo)準(zhǔn)發(fā)布之前(C++11)姨蝴,類是通過將其拷貝構(gòu)造函數(shù)和拷貝賦值運(yùn)算符聲明為private的來阻止拷貝
  • 聲明但不定義一個成員函數(shù)是合法的
  • 希望阻止拷貝的類應(yīng)用應(yīng)該使用=delete來定義它們自己的拷貝構(gòu)造函數(shù)和拷貝賦值運(yùn)算符俊啼,而不應(yīng)該將它們聲明為private

拷貝控制和資源管理

  • 一旦一個類需要析構(gòu)函數(shù),那么幾乎肯定它也需要一個拷貝構(gòu)造函數(shù)和一個拷貝控制運(yùn)算符
行為像值的類
  • 當(dāng)編寫賦值運(yùn)算符時左医,以下兩點(diǎn)需要記住
- [x] 如果一個對象賦予它自身吨些,賦值運(yùn)算符必須能正確工作
- [x] 大多數(shù)賦值運(yùn)算符組合了析構(gòu)函數(shù)和拷貝構(gòu)造函數(shù)的工作
  • 當(dāng)你編寫一個賦值運(yùn)算符,一個好的模式是先將右側(cè)的運(yùn)算對象拷貝到一個局部臨時對象中炒辉,當(dāng)拷貝完成后,銷毀左側(cè)運(yùn)算對象的現(xiàn)有成員就是安全的了泉手,一旦左側(cè)運(yùn)算對象的資源被銷毀黔寇,就只剩下將數(shù)據(jù)從臨時對象拷貝到左側(cè)運(yùn)算對象的成員中了
  • 對于一個賦值運(yùn)算符來說,正確工作是非常重要的斩萌,即使是將一個對象賦予它自身缝裤,也要能正確工作,一個好的方法是在銷毀左側(cè)運(yùn)算對象資源之前拷貝右側(cè)運(yùn)算對象
定義行為像指針的類
  • 對于行為類似指針的類颊郎,我們需要為其定義拷貝構(gòu)造函數(shù)和拷貝賦值運(yùn)算符憋飞,來拷貝指針成員本身而不是它指向的string,我們的類仍需自己的析構(gòu)函數(shù)來釋放接受string參數(shù)的構(gòu)造函數(shù)分配的內(nèi)存
  • 一個令類展現(xiàn)類似指針的行為的最好方法是使用shared_ptr來管理類中的資源
  • 當(dāng)我們希望直接管理資源的時候姆吭,就要使用引用計數(shù)
  • 引用計數(shù)的工作方式如下:
- [x] 除了初始化對象外榛做,每個構(gòu)造函數(shù)(拷貝構(gòu)造函數(shù)除外)還有創(chuàng)建一個引用計數(shù),用來記錄有多少對象與正在創(chuàng)建的對象共享狀態(tài),當(dāng)我們創(chuàng)建一個對象時检眯,只有一個對象共享狀態(tài)厘擂,因此計數(shù)器初始化為1
- [x] 拷貝構(gòu)造函數(shù)不分配新的計數(shù)器,而是拷貝給定的數(shù)據(jù)成員锰瘸,包括計數(shù)器刽严,拷貝構(gòu)造函數(shù)遞增共享的計數(shù)器,指出給定對象是的狀態(tài)又被一個新用戶所共享
- [x] 析構(gòu)函數(shù)遞減計數(shù)器避凝,指出共享狀態(tài)的用戶少了一個舞萄,如果計數(shù)器變?yōu)?,則析構(gòu)函數(shù)釋放狀態(tài)
- [x] 拷貝賦值運(yùn)算符遞增右側(cè)運(yùn)算對象的計數(shù)器管削,遞減左側(cè)運(yùn)算對象的計數(shù)器倒脓,如果左側(cè)運(yùn)算對象的計數(shù)器變?yōu)?,意味著它的共享狀態(tài)沒有用戶了佩谣,拷貝賦值運(yùn)算符就必須銷毀狀態(tài)
  • 引用計數(shù)器保存在動態(tài)內(nèi)存中把还,當(dāng)創(chuàng)建一個對象時,我們也分配一個新的計數(shù)器茸俭,當(dāng)拷貝或賦值對象時吊履,我們拷貝指向計數(shù)器的指針,使用這種方法调鬓,副本和原對象都會指向相同的計數(shù)器

交換操作

  • 除了定義拷貝控制成員艇炎,管理資源的類通常還定義一個名為swap的函數(shù),對于哪些與重排元素順序的算法一起使用的類腾窝,定義swap是非常重要的缀踪,這類算法在需要交換兩個元素時會調(diào)用swap
  • 如果一個類定義了自己的swap,那么算法將會使用類自定義版本虹脯,否則驴娃,算法將使用標(biāo)準(zhǔn)庫定義的swap
  • 如下為swap實(shí)現(xiàn)的兩種方式
/*交換值空間*/
HasPtr temp = v1;   //創(chuàng)建v1的值的一個臨時副本
v1 = v2;            //將v2的值賦予v1
v2 = temp;          //將保存的v1的值賦予v2

/*直接交換指針*/
string * temp = v1.ps;  //為v1.ps中的指針創(chuàng)建一個副本
v1.ps = v2.ps;          //將v2.ps中的指針賦予v1.ps
v2.ps = temp;           //將保存的v1.ps中原來的指針賦予v2.ps
  • swap的經(jīng)典實(shí)現(xiàn)如下
class HasPtr{
    friend void swap(HasPtr & , HasPtr &);
    //其余成員定義
};

inline void swap(HasPtr & 1hs, HasPtr & rhs){
    using std::swap;
    swap(1hs.ps,rhs.ps);
    swap(1hs.i,rhs,i);
} 
  • 與拷貝控制成員不同,swap并不是必要的循集,但對于分配了資源的類唇敞,定義swap可能是一種很重要的優(yōu)化手段
  • swap函數(shù)應(yīng)該調(diào)用swap,而不是std::swap
  • 如果一個類的成員有自己類型特定的swap函數(shù)咒彤,調(diào)用std::swap就是錯誤的疆柔,反之則正確

動態(tài)內(nèi)存管理類

  • 以下將實(shí)現(xiàn)標(biāo)準(zhǔn)庫vector類的一個簡化版本,非模板且僅適用與string镶柱,將其命名為StrVec
  • 每個StrVec有三個指針成員指向其元素所使用的內(nèi)存:
- [X] elements,指向分配的內(nèi)存中的首元素
- [x] first_free,指向最后一個實(shí)際元素之和的位置
- [x] cap,指向分配的內(nèi)存末尾之后的位置
  • 上述指針的含義如下圖
    ![Capture.PNG-17.2kB][1]
  • StrVec定義如下
class StrVec{
public:
       StrVec():
           elements(nullptr),first_ptr(nullptr),cap(nullptr){}
       StrVec(const StrVec &);              //拷貝構(gòu)造函數(shù)
       StrVec & operator=(const StrVec &);  //拷貝賦值運(yùn)算符
       ~StrVec();                           //析構(gòu)函數(shù)
       void push_back(const std::string &); //拷貝元素
       size_t size() const {return first_free - elements;}
       size_t capacity() const {return cap - elements;}
       std::string * begin() const {return elements;}
       std::string * end() const {return first_free;}
       //...

private:
       static std::allocator<std::string> alloc;    //分配元素
       /*被添加元素的函數(shù)所使用*/
       void chk_n_alloc(){
           if(size() == capacity())
               reallocate();
       }
       /*工具函數(shù)旷档,被拷貝構(gòu)造函數(shù),賦值運(yùn)算符和析構(gòu)函數(shù)所使用*/
       std::pair<std::string* , std::string*>alloc_n_copy(const std::string* , const std::string*);

       void free();                 //銷毀元素并釋放內(nèi)存
       void reallocate();           //獲得更多內(nèi)存并拷貝已有元素

       std::string * elements;      //指向數(shù)組首元素的指針
       std::string * first_ptr;     //指向數(shù)組第一個空閑元素的指針
       std::string * cap;           //指向數(shù)組尾后位置的指針
};

  • 上述代碼解釋
- [x] 默認(rèn)構(gòu)造函數(shù)(隱式的)默認(rèn)初始化alloc并(顯式的)將指針初始化為nullptr歇拆,表明沒有元素
- [x] size成員返回當(dāng)前真正在使用的元素的數(shù)目鞋屈,等于first_free --- elements
- [x] capacity成員返回StrVec可以保存的元素的數(shù)量范咨,等價于cap --- elements
- [x] 當(dāng)沒有空間容納新元素,即cap==first_free時谐区,chk_n_alloc會為StrVec重新分配內(nèi)存
- [x] begin和end成員分別返回指向首元素(即elements)和最后一個構(gòu)造的元素之和的位置(即first_free)的指針
  • 使用alloctor的時候湖蜕,必須記住內(nèi)存是未構(gòu)造的,為了使用此原始內(nèi)存宋列,必須調(diào)用construct昭抒,在內(nèi)存中構(gòu)造一個對象,alloctor的使用如下
    allocator<int> alloc;               //構(gòu)建int分配內(nèi)存的alloctor
    int * temp = alloc.allocate(10);    //分配10個int對象的空間炼杖,而不調(diào)用構(gòu)造函數(shù)
    alloc.construct(temp);              //在第一個對象的內(nèi)存上通過缺省構(gòu)造函數(shù)構(gòu)建對象
    alloc.construct(temp+1,6);          //在第二個對象的內(nèi)存上通過有參構(gòu)造函數(shù)構(gòu)建對象
    alloc.destroy(temp+1);              //調(diào)用第二個對象的析構(gòu)函數(shù)(不釋放內(nèi)存)
    alloc.destroy(temp);                //調(diào)用第一個對象的析構(gòu)函數(shù)(不釋放內(nèi)存)
    alloc.deallocate(temp,10);          //釋放內(nèi)存

對象移動

  • 標(biāo)準(zhǔn)容器庫灭返,string和shared_ptr類既支持移動也支持拷貝,IO類和unique_ptr類可以移動但不可以拷貝
右值引用
  • 右值引用就是必須綁定到右值的引用坤邪,我們通過&&而不是&來獲得右值的引用
  • 右值引用只能綁定到一個將要銷毀的對象
  • 常規(guī)引用被稱為左值引用
  • 左值引用不能將其綁定到要求轉(zhuǎn)換的表達(dá)式/字面常量或是返回右值的表達(dá)式
  • 右值引用有著完全相反的特性熙含,我們可以將一個右值引用綁定到這類表達(dá)式上,但不能將一個右值引用直接綁定到一個左值上
int i = 42;
int & r = i;                //正確艇纺,r引用i
int && rr = i;              //錯誤怎静,不能將一個右值引用綁定到一個左值上
int & r2 = i * 42;          //錯誤,i*42是一個右值
const int & r3 = i * 42;    //正確黔衡,常量引用可以綁定右值
int && rr2 = i * 42;        //正確蚓聘,將右值引用rr2綁定在乘法結(jié)果上
  • 返回左值引用的函數(shù),連同賦值/下標(biāo)/解引用和前置遞增/遞減運(yùn)算符盟劫,都是返回左值表達(dá)式的例子夜牡,我們可以將一個左值引用綁定到這類表達(dá)式的結(jié)果上
  • 返回非音樂類型的函數(shù),連同算數(shù)/關(guān)系/位以及后置遞增/遞減運(yùn)算符侣签,都生成右值塘装,我們不能將一個左值引用綁定到這類表達(dá)式上,但我們可以將一個const的左值引用或者一個右值引用綁定到這類表達(dá)式上
  • 左值有持久的狀態(tài)影所,而右值要么是字面常量有蹦肴,要么是在表達(dá)式求值過程中創(chuàng)建的臨時對象
  • 由右值引用只能綁定到臨時對象可知
- [x] 所引用的對象將要被銷毀
- [x] 該對象沒有其他用戶
  • 使用右值引用的代碼可以自由的接管所引用的對象的資源
  • 右值引用指向?qū)⒁讳N毀的對象,因此猴娩,我們可以從綁定到右值的對象竊取狀態(tài)
  • 變量是左值冗尤,因此我們不能將一個右值引用直接綁定到一個變量上,即使這個變量是右值引用類型也不行
  • 我們可以銷毀一個移動后源對象胀溺,也可以賦予它新值,但不能使用一個移后源對象的值
  • 使用move的代碼應(yīng)該使用std::move而不是move皆看,這樣可以避免潛在的名字沖突
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仓坞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子腰吟,更是在濱河造成了極大的恐慌无埃,老刑警劉巖徙瓶,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嫉称,居然都是意外死亡侦镇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門织阅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來壳繁,“玉大人,你說我怎么就攤上這事荔棉∧致” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵润樱,是天一觀的道長渣触。 經(jīng)常有香客問我,道長壹若,這世上最難降的妖魔是什么嗅钻? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮店展,結(jié)果婚禮上养篓,老公的妹妹穿的比我還像新娘。我一直安慰自己壁查,他們只是感情好觉至,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著睡腿,像睡著了一般语御。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上席怪,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天应闯,我揣著相機(jī)與錄音,去河邊找鬼挂捻。 笑死碉纺,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的刻撒。 我是一名探鬼主播骨田,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼声怔!你這毒婦竟也來了态贤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤醋火,失蹤者是張志新(化名)和其女友劉穎悠汽,沒想到半個月后箱吕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柿冲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年茬高,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片假抄。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡怎栽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出慨亲,到底是詐尸還是另有隱情婚瓜,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布刑棵,位于F島的核電站巴刻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛉签。R本人自食惡果不足惜胡陪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碍舍。 院中可真熱鬧柠座,春花似錦、人聲如沸片橡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捧书。三九已至吹泡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間经瓷,已是汗流浹背爆哑。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舆吮,地道東北人揭朝。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像色冀,于是被迫代替她去往敵國和親潭袱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355