C++11 特性

C++ 11引入了大量非常有用的特性勇垛,使代碼更直觀扎运、安全瑟曲、簡潔、方便豪治。
此處列舉的僅是一部分較常用的特性洞拨,完整的列表還需參考官方文檔或者微軟的文檔:Support For C++11/14/17 Features (Modern C++)

初始化列表 Initializer List

所有STL容器都支持初始化列表,如下:

std::vector<int> v = { 1, 2, 3 };
std::list<int> l = { 1, 2, 3 };
std::set<int> s = { 1, 2, 3 };
std::map<int, std::string> m = { {1, "a"}, {2, "b"} };

在自定義class上支持初始化列表

#include <initializer_list>

class A {
public:
    B(const std::initializer_list<int>& items)
        : m_items(items)
    {}

private:
    std::vector<int> m_items;
};

A a1 = { 1, 2, 3 };
// 或者
A a2{ 1, 2, 3 };

統(tǒng)一的初始化方法 Uniform Initialization

可以統(tǒng)一使用大括號(hào){}進(jìn)行初始化负拟。對構(gòu)造函數(shù)的選擇的優(yōu)先級如下:

class A {
public:
    // first choice
    A(const std::initializer_list<int>& v) : age(*v.begin())
    {}

    // second choice
    A(int age) : age(age)
    {}

    // third choice
    int age;
};

A a{ 5 };

上面的調(diào)用會(huì)選擇帶初始化列表的構(gòu)造函數(shù)烦衣。

class A {
public:
    A() {}

    int age;
};

A a{ 5 };

這個(gè)代碼會(huì)編譯出錯(cuò)。因?yàn)榇嬖跇?gòu)造函數(shù)掩浙,但函數(shù)簽名又不匹配花吟。換言之,只要存在自定義的構(gòu)造函數(shù)厨姚,就要求至少有一個(gè)構(gòu)造函數(shù)的參數(shù)列表與大括號(hào)中的參數(shù)完全匹配衅澈,才能使用這種方式初始化。

類型推導(dǎo) Auto Type

過去的這種冗長的類型聲明

std::map<int, std::string>::const_iterator itr = m.find(1);

現(xiàn)在可以寫成這樣了

auto itr = m.find(1);

編譯器會(huì)自動(dòng)推導(dǎo)出正確的類型谬墙。字面量也可以:

auto i = 1;          // int
auto d = 1.1;        // double
auto s = "hi";       // const char*
auto a = { 1, 2 };   // std:: initializer_list<int>

如果是用Visual Studio矾麻,把鼠標(biāo)懸停在變量名上方纱耻,可以看到推導(dǎo)后的類型名稱。類型推導(dǎo)對于泛型編程非常方便险耀,比如:

template<typename T, typename K>
auto add(T a, K b) {
    return a + b;
}

auto a = add(1, 2);     // int add(int, int)
auto b = add(1, 2.2);   // double add(int, double)

留意第二個(gè)調(diào)用弄喘,返回值被正確地推斷為double類型。

遍歷 foreach

以前遍歷vector一般是這么寫的

for (std::vector<int>::const_iterator itr = v.begin(); itr != v.end(); ++itr) {
    std::cout << *itr << std::endl;
}

這樣寫有兩個(gè)缺點(diǎn):

  1. 迭代器聲明很冗長 (用auto可以部分解決)
  2. 循環(huán)內(nèi)部必須對迭代器解引用(主要是難看)

可以使用的新的遍歷方式:

for (int i : v) {
    std::cout << i << std::endl;
}

代碼立馬簡潔了許多甩牺。但是要注意蘑志,這里每次循環(huán),會(huì)對i進(jìn)行一次拷貝贬派。此處i是一個(gè)int值急但,拷貝不會(huì)造成問題,但是如果是一個(gè)class搞乏,我們就更希望用引用的方式進(jìn)行遍歷波桩,一般寫成:

std::vector<string> v = { "a", "b" };

for (auto& s : v) {
    std::cout << s << std::endl;
}

auto&即可以變成引用方式遍歷,甚至還能在循環(huán)中改變它的值请敦。也可以使用const auto&镐躲,只是一般沒有必要。

空指針 nullptr

以往我們使用NULL表示空指針侍筛。它實(shí)際上是個(gè)為0的int值萤皂。下面的代碼會(huì)產(chǎn)生岐義:

void f(int i) {} // chose this one
void f(const char* s) {}

f(NULL);

為此C++ 11新增類型nullptr_t,它只有一個(gè)值nullptr匣椰。上面的調(diào)用代碼可以寫成:

void f(int i) {}
void f(const char* s) {} // chose this one

f(nullptr);

強(qiáng)類型枚舉 enum class

原來的enum有兩個(gè)缺點(diǎn):

  1. 容易命名沖突
  2. 類型不嚴(yán)格

如下代碼:

enum Direction {
    Left, Right
};

enum Answer {
    Right, Wrong
};

此代碼編譯報(bào)錯(cuò):Right重定義裆熙。這里使用了單個(gè)單詞作為名稱,很容易出現(xiàn)沖突禽笑。所以我們一般加個(gè)前綴入录,變成:

enum Direction {
    Direction_Left, Direction_Right
};

enum Answer {
    Answer_Right, Answer_Wrong
};

這樣寫很難看,而且如果這兩個(gè)枚舉是分別從兩個(gè)第三方庫引入的佳镜,那就無法自己改名字了纷跛。而且改成這樣依然有個(gè)問題:

auto a = Direction_Left;
auto b = Answer_Right;

if (a == b)
    std::cout << "a == b" << std::endl;
else
    std::cout << "a != b" << std::endl;

這個(gè)代碼將輸出a == b,因?yàn)檫@兩上值都為0邀杏。然而允許兩個(gè)不同類型的值作比較贫奠,就是不合理的,容易隱藏一些bug望蜡。

C++ 11引入了enum class

enum class Direction {
    Left, Right
};

enum class Answer {
    Right, Wrong
};

auto a = Direction::Left;
auto b = Answer::Right;

if (a == b)
    std::cout << "a == b" << std::endl;
else
    std::cout << "a != b" << std::endl;
  • 引用時(shí)必須加上枚舉名稱(Direction_Left變成Direction::Left)唤崭,似乎寫法上差不多,但是這樣類型更加嚴(yán)格脖律。下面的a == b編譯將會(huì)報(bào)錯(cuò)谢肾,因?yàn)樗鼈兪遣煌念愋汀?/li>
  • 枚舉值不再是全局的,而是限定在當(dāng)前枚舉類型的域內(nèi)小泉。所以使用單個(gè)單詞作為值的名稱也不會(huì)出現(xiàn)沖突芦疏。

靜態(tài)斷言 static assert

static_assert可在編譯時(shí)作判斷冕杠。

static_assert( size_of(int) == 4 );

構(gòu)造函數(shù)的相互調(diào)用 delegating constructor

同一個(gè)class的多個(gè)構(gòu)造函數(shù)的內(nèi)部實(shí)現(xiàn)通常非常相似,比如:

class A {
public:
    A(int x, int y, const std::string& name) : x(x), y(y), name(name) {
        if (x < 0 || y < 0)
            throw std::runtime_error("invalid coordination");
        // other stuff
    }

    A(int x, int y) : x(x), y(y), name("A") {
        if (x < 0 || y < 0)
            throw std::runtime_error("invalid coordination");
        // other stuff
    }

    A() : x(0), y(0), name("A") {
        // other stuff
    }

private:
    int x;
    int y;
    std::string name;
};

為了避免重復(fù)代碼酸茴,通常會(huì)把共同的代碼挪到一個(gè)init成員函數(shù)里:

class A {
public:
    A(int x, int y, const std::string& name) {
        init(x, y, name);
    }

    A(int x, int y) {
        init(x, y, "A");
    }

    A() {
        init(0, 0, "A");
    }

private:
    void init(int x, int y, const std::string& name) {
        if (x < 0 || y < 0)
            throw std::runtime_error("invalid coordination");
        this->x = x;
        this->y = y;

        if (name.empty())
            throw std::runtime_error("empty name");
        this->name = name;

        // other stuff
    }

private:
    int x;
    int y;
    std::string name;
};

這樣寫有三個(gè)問題:

  1. 二次賦值分预。執(zhí)行到init函數(shù)時(shí),數(shù)據(jù)成員實(shí)際已經(jīng)初始化了薪捍。比如name成員笼痹,此時(shí)已經(jīng)初始化為一個(gè)空字符串了。這里實(shí)際上是又調(diào)用了一次“=”操作符酪穿。對于初始化成本比較高的類型凳干,這樣做就有可能影響性能了。
  2. 只能調(diào)用成員的無參構(gòu)造函數(shù)被济。只有構(gòu)造函數(shù)的初始化列表才能調(diào)用成員的帶參數(shù)構(gòu)造函數(shù)救赐。
  3. 無法保證init只被調(diào)用一次。有些初始化步驟必須保證只被執(zhí)行一次只磷,這一點(diǎn)只有構(gòu)造函數(shù)可以保證经磅。

C++ 11允許構(gòu)造函數(shù)之間相互調(diào)用了:

class A {
public:
    A(int x, int y, const std::string& name) : x(x), y(y), name(name) {
        if (x < 0 || y < 0)
            throw std::runtime_error("invalid coordination");
        if (name.empty())
            throw std::runtime_error("empty name");
        // other stuff
    }

    A(int x, int y) : A(x, y, "A")
    {}

    A() : A(0, 0)
    {}

private:
    int x;
    int y;
    std::string name;
};

除了優(yōu)雅地解決了上述三個(gè)問題之外,代碼也簡潔了許多喳瓣,連name成員的默認(rèn)值"A"也只需要寫一次。

禁止重寫 final

  • 禁止虛函數(shù)被重寫
class A {
public:
    virtual void f1() final {}
};

class B : public A {
    virtual void f1() {}
};

此代碼編譯報(bào)錯(cuò)赞别,提示不能重寫f1畏陕。雖然f1是虛函數(shù),但是因?yàn)橛?code>final關(guān)鍵字仿滔,保證它不會(huì)被重寫惠毁。你可能會(huì)說,那不聲明virtual不就完了崎页。但是如果A本身也有基類鞠绰,f1是繼承下來的,那virtual就是隱含的了飒焦。

  • 禁止類被繼承
class A final {
};

class B : public A {
};

此代碼編譯報(bào)錯(cuò)蜈膨,提示不能繼承A

顯式聲明重寫 override

class A {
public:
    virtual void f1() const {}
};

class B : public A {
    virtual void f1() {}
};

上面的代碼在重寫函數(shù)f1時(shí)不小心漏了const牺荠,但是編譯器不會(huì)報(bào)錯(cuò)翁巍。因?yàn)樗恢滥闶且貙?code>f1,而認(rèn)為你是定義了一個(gè)新的函數(shù)休雌。這樣的情況也發(fā)生在基類的函數(shù)簽名變化時(shí)灶壶,子類如果沒有全部統(tǒng)一改過來,編譯器也不能發(fā)現(xiàn)問題杈曲。
C++ 11引入了override聲明驰凛,使重寫更安全胸懈。

class B : public A {
    virtual void f1() override {}
};

此時(shí)編譯報(bào)錯(cuò),提示找不到重寫的函數(shù)恰响。

定義成員初始值

當(dāng)我們?yōu)橐粋€(gè)class增加成員變量時(shí)趣钱,要注意在所有構(gòu)造函數(shù)中都對它進(jìn)行初始化(除非這個(gè)成員的默認(rèn)構(gòu)造函數(shù)就滿足我們的要求)。雖然C++ 11允許構(gòu)造函數(shù)相互調(diào)用渔隶,但至少該成員變量的聲明和初始化是分開寫的羔挡,導(dǎo)致后者經(jīng)常被遺忘。現(xiàn)在C++ 11可以在聲明成員變量的時(shí)直接賦初始值间唉。

class A {
public:
    int m = 1;
};

這個(gè)初始化的動(dòng)作會(huì)在所有構(gòu)造函數(shù)之前執(zhí)行绞灼,可以理解為這些初始值會(huì)被自動(dòng)放到初始化列表。如果初始化列表也有個(gè)初始化呈野,則選用初始化列表的值低矮。

class A {
public:
    A() : m(2)
    {}

    int m = 1; // 這個(gè)1被忽略
};

那實(shí)際上m會(huì)不會(huì)是先被初始化為1,再被改為2呢(二次賦值)被冒?我們用一個(gè)自定義的類作為成員變量:

class M {
public:
    M(int i) : i(i) {
        std::cout << "M(" << i << ")" << std::endl;
    }

    M(const M& other) : i(other.i) {
        std::cout << "copy M(" << i << ")" << std::endl;
    }

    M& operator = (const M& other) {
        i = other.i;
        std::cout << "= M(" << i << ")" << std::endl;
        return *this;
    }

private:
    int i;
};

class A {
public:
    A() : m(1)
    {}

private:
    M m = M(2);
};

A a;

我們?yōu)?code>M實(shí)現(xiàn)了三件套(構(gòu)造函數(shù)军掂,復(fù)制構(gòu)造函數(shù),賦值操作符)昨悼,并打印出信息蝗锥,這樣我們可以知道具體發(fā)生了什么。運(yùn)行結(jié)果:

M(1)

說明下面的M(2)直接被忽略了率触。

默認(rèn)構(gòu)造函數(shù) default

當(dāng)一個(gè)class有自定義構(gòu)造函數(shù)時(shí)终议,編譯器就不會(huì)自動(dòng)生成一個(gè)無參構(gòu)造函數(shù)。現(xiàn)在可以通過default關(guān)鍵字強(qiáng)制要求生成這個(gè)構(gòu)造函數(shù)葱蝗。

class A {
public:
    A(int i) {}
    A() = default;
};

當(dāng)然穴张,你也可以直接寫成

    A() {}

但用default意圖更加明確,編譯器也可以相應(yīng)地做優(yōu)化两曼。

刪除構(gòu)造函數(shù) delete

以往皂甘,當(dāng)我們需要隱藏構(gòu)造函數(shù)時(shí),可以把它聲明為private成員

class A {
private:
    A();
};

現(xiàn)在可以使用delete關(guān)鍵字

class A {
public:
    A() = delete;
};

常量表達(dá)式 constexpr

int size() { return 3; }
int a[size()];

上面的代碼編譯失敗悼凑,因?yàn)殪o態(tài)數(shù)組的大小必須在編譯期確定偿枕。改成:

constexpr int size() { return 3; }
int a[size()];

加上了constexpr,函數(shù)size變成在編譯期計(jì)算户辫,返回值被看成一個(gè)常量益老。

字符串字面量

const char* a = "string a";
const char* b = u8"string b";       // UTF-8
const char16_t* c = u"string c";    // UTF-16
const char32_t* d = U"string d";    // UTF-32
const char* e = R"(string e1 "\\
    stirng e2)";                    // raw string

std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
std::cout << d << std::endl;
std::cout << e << std::endl;

輸出結(jié)果:


第1、2行沒問題寸莫;第3捺萌、4行實(shí)際是打印出了內(nèi)存地址,因?yàn)?code>std::cout不支持這兩種類型。
第5種比較有意思桃纯,它是忽略了轉(zhuǎn)義符的字符串酷誓。從這個(gè)例子可以看到:

  • 它的格式是R"(...)",中間的...是內(nèi)容态坦。
  • 內(nèi)容可以出現(xiàn)"符號(hào)而不會(huì)截?cái)嘧址?/li>
  • 轉(zhuǎn)義符\被當(dāng)成一個(gè)字符
  • 換行也被當(dāng)成字符串的內(nèi)容(如果要忽略換行符盐数,則在換行前使用\連接符)。
  • 縮進(jìn)也被當(dāng)成內(nèi)容伞梯。

利用這個(gè)特性玫氢,這樣的代碼:

auto xml = "<root>\n"
    "\t<item value=\"1\">\n"
    "\t<item value=\"2\">\n"
    "</root>";

就可以直接寫成:

auto xml = R"(<root>
    <item value="1">
    <item value="2">
</root>)";

不足之處就是會(huì)破壞代碼的縮進(jìn),因?yàn)榭s進(jìn)也被看成是字符串的內(nèi)容谜诫。

Lambda函數(shù)

這是個(gè)非常強(qiáng)大的重量級功能漾峡。簡單地講,就是可以用它定義一個(gè)臨時(shí)的函數(shù)對象喻旷,它像其它對象一樣可以傳遞和保存生逸。更為強(qiáng)大的是,它甚至可以訪問當(dāng)前函數(shù)的上下文且预。

特性

  1. 調(diào)用
auto add = [](int a, int b) { return a + b; };
std::cout << add(1, 2) << std::endl;
  • =后面的部分就是Lambda函數(shù)槽袄。先忽略前面的[]()里面的是參數(shù)列表锋谐,{}里面的是實(shí)現(xiàn)遍尺。跟普通的函數(shù)基本一樣。
  • 這里沒有聲明返回值類型涮拗,編譯器會(huì)根據(jù)return語句推導(dǎo)乾戏。如果有多個(gè)return語句,而且類型不一樣多搀,則會(huì)報(bào)錯(cuò)歧蕉。
  • 使用方式與普通函數(shù)一樣灾部。
  1. 傳遞
template<typename filter_func>
void print(const std::vector<int>& v, filter_func filter) {
    for (auto i : v) {
        if (filter(i))
            std::cout << i << std::endl;
    }
}

bool isGreaterThanTen(int i) {
    return i > 10;
}

class GreaterThanTenFilter {
public:
    bool operator()(int i) {
        return i > 10;
    }
};

std::vector<int> v = { 5, 10, 15, 20 };
print(v, isGreaterThanTen);         // 輸出 15 20
print(v, GreaterThanTenFilter());   // 輸出 15 20

以上代碼分別使用了函數(shù)指針和函數(shù)對象來指定過濾條件康铭。這兩種方式存在以下缺點(diǎn):

  • 代碼冗余。需要單獨(dú)定義一個(gè)函數(shù)或class才能實(shí)現(xiàn)赌髓。
  • filter_func的類型不明確从藤。此處filter_func是一個(gè)參數(shù)為一個(gè)int,返回值為bool型的函數(shù)锁蠕。但是這一點(diǎn)無法從函數(shù)聲明看出來夷野。并且函數(shù)對象使用()操作符語義也不明確。
  • print函數(shù)必須使用模板荣倾。雖然print內(nèi)部并沒有使用泛型的必要悯搔,但是考慮到兼容函數(shù)指針和函數(shù)對象的用法,也只能使用模板實(shí)現(xiàn)舌仍。
  • 不靈活妒貌。如果這個(gè)10是一個(gè)運(yùn)行時(shí)才確定的數(shù)字n通危,就需要修改函數(shù)對象才能實(shí)現(xiàn)。(函數(shù)指針無法實(shí)現(xiàn))

使用Lambda

#include <functional>

void print(const std::vector<int>& data, std::function<bool(int)> filter) {
    for (auto i : data) {
        if (filter(i))
            std::cout << i << std::endl;
    }
 }

std::vector<int> v = { 5, 10, 15, 20 };
print(v, [](int i) { return i > 10; });     // 輸出 15 20

解決了上面提到的幾個(gè)問題:

  • 代碼簡潔灌曙。無需另外定義函數(shù)或class即可實(shí)現(xiàn)菊碟。整體代碼縮小了不少。
  • 類型明確在刺。新增的std::function是一個(gè)通用的函數(shù)對象逆害,可以使用Lambda初始化。最大的優(yōu)點(diǎn)是參數(shù)和返回值都是明確的蚣驼,可以從聲明看出來魄幕。
  • 無須使用模板。
  • 更靈活隙姿。這一點(diǎn)接下來講梅垄。
  1. 可以訪問當(dāng)前函數(shù)的上下文
    上面的例子如果把硬編碼的10改成變量n,只需要改調(diào)用的地方:
int n = 10;
print(v, [=](int i) { return i > n; });

可以看到前面的[]改成了[=]输玷,這表示Lambda使用值傳遞的方式捕獲外部變量队丝。
[]表示捕獲列表,用來描述Lambda訪問外部變量的方式欲鹏。如下:

捕獲列表 作用
[a] a為值傳遞
[a, &b] a為值傳遞机久,b為引用傳遞
[&] 所有變量都用引用傳遞。當(dāng)前對象(即this指針)也用引用傳遞赔嚎。
[=] 所有變量都用值傳遞膘盖。當(dāng)前對象用引用傳遞。

注意事項(xiàng)

  • 捕獲時(shí)機(jī)
int i = 1;
auto f = [=]() { std::cout << i << std::endl; };
i = 2;
f(); // 輸出 1

可以看出尤误,在定義Lambda的地方就已經(jīng)捕獲到i的值侠畔。后面修改i也不影響f的輸出。
如果把[=]改成[&]损晤,則會(huì)輸出2软棺。因?yàn)?code>Lambda實(shí)際上只捕獲到i的引用。

  • 局部變量的生命周期
std::function<void()> GetLambda() {
    int i = 1;
    return [&]() { std::cout << i << std::endl; };
}

auto f = GetLambda();
f(); // 輸出 -858993460 之類的亂碼

使用引用的方式訪問局部變量時(shí)尤勋,要注意Lambda的生命周期不能超過該局部變量的生命周期喘落。

內(nèi)部實(shí)現(xiàn)

(待續(xù)……)

參考資料:
Learn C++ 11 in 20 Minutes - Part I
Learn C++ 11 in 20 Minutes - Part II
Support For C++11/14/17 Features (Modern C++)
Lambda 表達(dá)式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市最冰,隨后出現(xiàn)的幾起案子瘦棋,更是在濱河造成了極大的恐慌,老刑警劉巖暖哨,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赌朋,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)沛慢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門服球,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颠焦,你說我怎么就攤上這事斩熊。” “怎么了伐庭?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵粉渠,是天一觀的道長。 經(jīng)常有香客問我圾另,道長霸株,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任集乔,我火速辦了婚禮去件,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扰路。我一直安慰自己尤溜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布汗唱。 她就那樣靜靜地躺著宫莱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哩罪。 梳的紋絲不亂的頭發(fā)上授霸,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音际插,去河邊找鬼碘耳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛框弛,可吹牛的內(nèi)容都是我干的辛辨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼功咒,長吁一口氣:“原來是場噩夢啊……” “哼愉阎!你這毒婦竟也來了绞蹦?” 一聲冷哼從身側(cè)響起力奋,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎幽七,沒想到半個(gè)月后景殷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年猿挚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咐旧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绩蜻,死狀恐怖铣墨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情办绝,我是刑警寧澤伊约,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站孕蝉,受9級特大地震影響屡律,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜降淮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一超埋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧佳鳖,春花似錦霍殴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至淑玫,卻和暖如春巾腕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背絮蒿。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工尊搬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人土涝。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓佛寿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親但壮。 傳聞我的和親對象是個(gè)殘疾皇子冀泻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容