六淌喻、多態(tài)與虛函數(shù)

多態(tài)的基本概念

多態(tài)

  • 多態(tài)分為編譯時(shí)多態(tài)和運(yùn)行時(shí)多態(tài)盛险。
  • 編譯時(shí)多態(tài)主要是指函數(shù)的重載(包括運(yùn)算符的重載)瞄摊。對(duì)重載函數(shù)的調(diào)用,在編譯時(shí)就可以根據(jù)實(shí)參確定應(yīng)該調(diào)用哪個(gè)函數(shù)苦掘,因此稱為編譯時(shí)多態(tài)换帜。
  • 運(yùn)行時(shí)多態(tài)則和繼承、虛函數(shù)等概念有關(guān)鹤啡。本章中提及的多態(tài)主要是指運(yùn)行時(shí)多態(tài)惯驼。
  • 程序編譯階段都早于程序運(yùn)行階段,所以靜態(tài)綁定稱為早綁定递瑰,動(dòng)態(tài)綁定稱為晚綁定祟牲。靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)的區(qū)別,只在于在什么時(shí)候?qū)⒑瘮?shù)實(shí)現(xiàn)和函數(shù)調(diào)用關(guān)聯(lián)起來抖部,是在編譯階段還是在運(yùn)行階段说贝,即函數(shù)地址是早綁定的還是晚綁定的。
  • 在類之間滿足賦值兼容的前提下慎颗,實(shí)現(xiàn)動(dòng)態(tài)綁定必須滿足以下兩個(gè)條件:
    1. 必須聲明虛函數(shù)
    2. 通過基類類型的引用或者指針調(diào)用虛函數(shù)

虛函數(shù)

  • 所謂“虛函數(shù)”乡恕,就是在函數(shù)聲明時(shí)前面加了virtual關(guān)鍵字的成員函數(shù)。virtual關(guān)鍵字只在類定義中的成員函數(shù)聲明處使用俯萎,不能在類外部寫成員函數(shù)體時(shí)使用傲宜。靜態(tài)成員函數(shù)不能是虛函數(shù)。包含虛函數(shù)的類稱為“多態(tài)類”夫啊。

  • 聲明虛函數(shù)成員的一般格式如下:

    virtual 函數(shù)返回值類型 函數(shù)名(行參表);
    
  • 在類的定義中使用virtual關(guān)鍵字來限定的成員函數(shù)即稱為虛函數(shù)函卒。再次強(qiáng)調(diào)一下,虛函數(shù)的聲明只能出現(xiàn)在類定義中的函數(shù)原型聲明時(shí)撇眯,不能在類外成員函數(shù)實(shí)現(xiàn)的時(shí)候谆趾。

  • 派生類可以繼承基類的同名函數(shù),并且可以在派生類中重寫這個(gè)函數(shù)叛本。如果不使用虛函數(shù),當(dāng)使用派生類對(duì)象調(diào)用這個(gè)函數(shù)彤钟,且派生類中重寫了這個(gè)函數(shù)時(shí)来候,則調(diào)用派生類中的同名函數(shù),即“隱藏”了基類中的函數(shù)逸雹。

  • 當(dāng)然营搅,如果還想調(diào)用基類的函數(shù)云挟,只需在調(diào)用函數(shù)時(shí),在前面加上基類名及作用域限定符即可转质。

關(guān)于虛函數(shù)园欣,有以下幾點(diǎn)需要注意

  1. 雖然將虛函數(shù)聲明為內(nèi)聯(lián)函數(shù)不會(huì)引起錯(cuò)誤,但因?yàn)閮?nèi)聯(lián)函數(shù)是在編譯階段進(jìn)行靜態(tài)處理的休蟹,而對(duì)虛函數(shù)的調(diào)用是動(dòng)態(tài)綁定的沸枯,所以虛函數(shù)一般不聲明為內(nèi)聯(lián)函數(shù)。
  2. 派生類重寫基類的虛函數(shù)實(shí)現(xiàn)多態(tài)赂弓,要求函數(shù)名绑榴。參數(shù)列表及返回值類型要完全相同。
  3. 基類中定義了虛函數(shù)盈魁,在派生類中該函數(shù)始終保持虛函數(shù)的特性翔怎。
  4. 只有類的非靜態(tài)成員函數(shù)才能定義為虛函數(shù),靜態(tài)成員函數(shù)和友元函數(shù)不能定義為虛函數(shù)杨耙。
  5. 如果虛函數(shù)的定義是在類體外赤套,則只需在聲明函數(shù)時(shí)添加virtual關(guān)鍵字,定義時(shí)不加virtual關(guān)鍵字珊膜。
  6. 構(gòu)造函數(shù)不能定義為虛函數(shù)容握。最好也不要將operator=定義為虛函數(shù),因?yàn)槭褂脮r(shí)容易混淆辅搬。
  7. 不要在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù)唯沮。在構(gòu)造函數(shù)和析構(gòu)函數(shù)中,對(duì)象是不完整的堪遂,可能會(huì)出現(xiàn)未定義的行為介蛉。
  8. 最好將基類的析構(gòu)函數(shù)聲明為虛函數(shù)。

通過基類指針實(shí)現(xiàn)多態(tài)

聲明虛函數(shù)后溶褪,派生類對(duì)象的地址可以賦值給基類指針币旧,也就是基類指針可以指向派生類對(duì)象。
對(duì)于通過基類指針調(diào)用基類和派生類中都有的同名猿妈、同參數(shù)表的虛函數(shù)的語句吹菱,編譯時(shí)系統(tǒng)并不確定要執(zhí)行的是基類還是派生類的虛函數(shù);
而當(dāng)程序運(yùn)行到該語句時(shí)彭则,
如果基類指針指向的是一個(gè)基類對(duì)象鳍刷,則調(diào)用基類的虛函數(shù);
如果基類指針指向的是一個(gè)派生類對(duì)象俯抖,則調(diào)用派生類的虛函數(shù)输瓜。

#include <iostream>
using namespace std;

class A {
public:
    virtual void Print() {
        cout << "A::Print" << endl;
    }
};

class B : public A {
public:
    virtual void Print() {
        cout << "B::Print" << endl;
    }
};

class D : public A {
public:
    virtual void Print() {
        cout << "D::Print" << endl;
    }
};

class E : public B {
public:
    virtual void Print() {
        cout << "E::Print" << endl;
    }
};

int main() {
    A a;
    B b;
    D d;
    E e;
    
    A *pa = &a;//基類pa指針指向基類對(duì)象a
    B *pb = &b;//派生類pb指針指向基類對(duì)象b
    
    pa->Print();//多態(tài),目前指向基類對(duì)象a,調(diào)用a.Print()
    
    pa = pb;//派生類指針賦值給基類指針尤揣,pa指向派生類對(duì)象b
    pa->Print();//多態(tài)搔啊,目前指向派生類對(duì)象b,調(diào)用b.Print()
    
    pa = &d;//基類指針pa指向派生類對(duì)象d
    pa->Print();//多態(tài)北戏,目前指向派生類對(duì)象d负芋,調(diào)用d.Print()
    
    pa = &e;//基類指針pa指向派生類對(duì)象e
    pa->Print();//多態(tài),目前指向派生類對(duì)象e嗜愈,調(diào)用e.Print()

    return 0;
};

通過基類引用實(shí)現(xiàn)多態(tài)

通過基類指針調(diào)用虛函數(shù)時(shí)可以實(shí)現(xiàn)多態(tài)旧蛾,通過基類的引用調(diào)用虛函數(shù)的語句也是多態(tài)的。
即通過基類的引用調(diào)用基類和派生類中同名芝硬、同參數(shù)表的虛函數(shù)時(shí)蚜点,
若其引用的是一個(gè)基類的對(duì)象,則調(diào)用的是基類的虛函數(shù)拌阴;
若其引用的是一個(gè)派生類的對(duì)象绍绘,則調(diào)用的是派生類的虛函數(shù)。

#include <iostream>
using namespace std;

class A {
public:
    virtual void Print() {
        cout << "A::Print" << endl;
    }
};

class B : public A {
public:
    virtual void Print() {
        cout << "B:Print" << endl;
    }
};

void PrintInfo(A &r) {
    //多態(tài)迟赃,使用基類引用調(diào)用哪個(gè)Print()陪拘,取決于r引用了哪個(gè)類的對(duì)象
    r.Print();
}

int main() {
    A a;
    B b;
    
    PrintInfo(a);//使用基類對(duì)象,調(diào)用基類中的函數(shù)
    PrintInfo(b);//使用派生類對(duì)象纤壁,調(diào)用派生類中的函數(shù)
    
    return 0;
}

多態(tài)的實(shí)現(xiàn)原理

多態(tài)的關(guān)鍵在于通過基類指針或引用調(diào)用一個(gè)虛函數(shù)時(shí)左刽,編譯階段不能確定到底調(diào)用的是基類還是派生類的函數(shù),運(yùn)行時(shí)才能確定酌媒。

派生類對(duì)象占用的存儲(chǔ)空間大小欠痴,等于基類成員變量占用的存儲(chǔ)空間大小加上派生類對(duì)象自身成員變量占用的存儲(chǔ)空間大小。

多態(tài)的使用

在普通成員函數(shù)(靜態(tài)成員函數(shù)秒咨、構(gòu)造函數(shù)和析構(gòu)函數(shù)除外)中調(diào)用其他虛成員函數(shù)也是允許的喇辽,并且是多態(tài)的。

#include <iostream>
using namespace std;

class CBase {
public:
    void func1() {
        cout << "CBase::func1()" << endl;
        func2();//在成員函數(shù)中調(diào)用虛函數(shù)
        func3();
    };
    virtual void func2() {
        cout << "CBase::func2()" << endl;
    };
    void func3() {
        cout << "CBase::func3()" << endl;
    };
};

class CDerived : public CBase {
public:
    virtual void func2() {
        cout << "CDerived::func2()" << endl;
    };
    void func3() {
        cout << "CDerived::func3()" << endl;
    };
};

int main() {
    CDerived d;
    d.func1();
    //CBase::func1()
    //CDerived::func2()
    //CBase::func3()

    return 0;
};

不僅能在成員函數(shù)中調(diào)用虛函數(shù)雨席,還可以在構(gòu)造函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù)菩咨,但這樣調(diào)用的虛函數(shù)不是多態(tài)的。

#include <iostream>
using namespace std;

class A {
public:
    virtual void hello() {
        cout << "A::hello" << endl;
    };
    virtual void bye() {
        cout << "A::bye" << endl;
    };
};

class B : public A {
public:
    virtual void hello() {
        cout << "B::hello" << endl;
    };
    B() {
        hello();//調(diào)用虛函數(shù)陡厘,但不是多態(tài)
    };
    ~B() {
        bye();//調(diào)用虛函數(shù)抽米,但不是多態(tài)
    };
};

class C : public B {
public:
    virtual void hello() {
        cout << "C::hello" << endl;
    };
};

int main() {
    C c;
    //B::hello
    //A::bye

    return 0;
};
  • 在構(gòu)造函數(shù)中調(diào)用的,編譯系統(tǒng)可以據(jù)此決定調(diào)用哪個(gè)類中的版本糙置,所以它不是多態(tài)的云茸;
  • 在析構(gòu)函數(shù)中調(diào)用的,所以也不是多態(tài)谤饭;
  • 實(shí)現(xiàn)多態(tài)時(shí)查辩,必須滿足的條件是:使用基類指針或引用來調(diào)用基類中聲明的虛函數(shù)胖笛。
  • 派生類中繼承自基類的虛函數(shù),可以寫virtual關(guān)鍵字宜岛,也可以省略這個(gè)關(guān)鍵字,這不影響派生類中的函數(shù)也是虛函數(shù)功舀。
#include <iostream>
using namespace std;

class A {
public:
    void func1() {
        cout << "A::func1" << endl;
    };
    virtual void func2() {//虛函數(shù)
        cout << "A::func2" << endl;
    };
};

class B : public A {
public:
    virtual void func1() {
        cout << "B::func1" << endl;
    };
    void func2() {//自動(dòng)成為虛函數(shù)
        cout << "B::func2" << endl;
    };
};

class C : public B {
public:
    void func1() {//自動(dòng)成為虛函數(shù)
        cout << "C::func1" << endl;
    };
    void func2() {//自動(dòng)成為虛函數(shù)
        cout << "C::func2" << endl;
    };
};

int main() {
    C c;
    A *pa = &c;
    B *pb = &c;
    
    pa->func2();//多態(tài) C::func2
    pa->func1();//因?yàn)榛惖膄unc1不是虛函數(shù)萍倡,這也的調(diào)用也不是多態(tài) A::func1
    pb->func1();//多態(tài) C::func1

    return 0;
};

虛析構(gòu)函數(shù)

  • 如果一個(gè)基類指針指向的對(duì)象是用new運(yùn)算符動(dòng)態(tài)生成的派生類對(duì)象,那么釋放該對(duì)象所占用的空間時(shí)辟汰,如果僅調(diào)用基類的析構(gòu)函數(shù)列敲,則只會(huì)完成該析構(gòu)函數(shù)內(nèi)的空間釋放,不會(huì)涉及派生類析構(gòu)函數(shù)內(nèi)的空間釋放帖汞,容易造成內(nèi)存泄露戴而。

  • 聲明虛析構(gòu)函數(shù)的一般格式如下:

    virtual ~類名();
    
  • 虛析構(gòu)函數(shù)沒有返回值類型,沒有參數(shù)翩蘸,所以它的格式非常簡(jiǎn)單所意。

  • 如果一個(gè)類的虛構(gòu)函數(shù)是虛函數(shù),則由他派生的所有子類的析構(gòu)函數(shù)也是虛析構(gòu)函數(shù)催首。使用虛析構(gòu)函數(shù)的目的是為了在對(duì)象消亡時(shí)實(shí)現(xiàn)多態(tài)扶踊。

#include <iostream>
using namespace std;

class ABase {
public:
    ABase() {
        cout << "ABase構(gòu)造函數(shù)" << endl;
    };
    virtual ~ABase() {
        cout << "ABase::析構(gòu)函數(shù)" << endl;
    };
};

class Derived : public ABase {
public:
    Derived() {
        cout << "Derived構(gòu)造函數(shù)" << endl;
    };
    ~Derived() {
        cout << "Derived::析構(gòu)函數(shù)" << endl;
    };
};

int main() {
    ABase *a = new Derived();
    delete a;
    //ABase構(gòu)造函數(shù)
    //Derived構(gòu)造函數(shù)
    //Derived::析構(gòu)函數(shù)
    //ABase::析構(gòu)函數(shù)

    return 0;
};
  • 可以看出,不僅調(diào)用了基類的析構(gòu)函數(shù)郎任,也調(diào)用了派生類的析構(gòu)函數(shù)
  • 只要基類的析構(gòu)函數(shù)是虛函數(shù)秧耗,那么派生類的析構(gòu)函數(shù)不論是否用virtual關(guān)鍵字聲明,都自動(dòng)成為虛析構(gòu)函數(shù)
  • 一般來說舶治,一個(gè)類如果定了虛函數(shù)分井,則最好將析構(gòu)函數(shù)也定義成虛函數(shù)。不過切記霉猛,構(gòu)造函數(shù)不能是虛函數(shù)

純虛函數(shù)和抽象類

純虛函數(shù)

  • 純虛函數(shù)的作用相當(dāng)于一個(gè)統(tǒng)一的接口形式尺锚,表明在基類的各派生類中應(yīng)該有這樣的一個(gè)操作,然后在各派生類中具體實(shí)現(xiàn)與本派生類相關(guān)的操作韩脏。

  • 純虛函數(shù)是聲明在基類中的虛函數(shù)缩麸,沒有具體的定義,而由個(gè)派生類根據(jù)實(shí)際需要給出各自的定義赡矢。

  • 聲明純虛函數(shù)的一般格式如下:

    virtual 函數(shù)類型 函數(shù)名(參數(shù)表) = 0;
    
  • 純虛函數(shù)沒有函數(shù)體杭朱,參數(shù)標(biāo)后要寫= 0。派生類中必須重寫這個(gè)函數(shù)吹散。按照純虛函數(shù)名調(diào)用時(shí)弧械,執(zhí)行的是派生類中重寫的語句,即調(diào)用的是派生類中的版本空民。

純虛函數(shù)不同于函數(shù)體為空的虛函數(shù)刃唐,
它們的不同之處如下:

  1. 純虛函數(shù)沒有函數(shù)體羞迷,而空的虛函數(shù)的函數(shù)體為空
  2. 純虛函數(shù)所在的類是抽象類,不能直接進(jìn)行實(shí)例化画饥;而空的虛函數(shù)所在的類是可以實(shí)例化的衔瓮。

它們的共同特點(diǎn)是:
純虛函數(shù)與函數(shù)體為空的虛函數(shù)都可以派生出新的類,然后在新類中給出虛函數(shù)的實(shí)現(xiàn)抖甘,而且這種新的實(shí)現(xiàn)具有多態(tài)特征热鞍。

抽象類

包含純虛函數(shù)的類稱為抽象類。因?yàn)槌橄箢愔杏猩形赐瓿傻暮瘮?shù)定義衔彻,所以它不能實(shí)例化一個(gè)對(duì)象薇宠。抽象類的派生類中,如果沒有給出全部純虛函數(shù)的定義艰额,則派生類繼續(xù)是抽象類澄港。直到派生類中給出全部純虛函數(shù)定義后,它才不再是抽象類柄沮,也才能實(shí)例化一個(gè)對(duì)象回梧。****雖然不能創(chuàng)建抽象類的對(duì)象,但可以定義抽象類的指針和引用铡溪。這樣的指針和引用可以指向并訪問派生類的成員漂辐,這種訪問具有多態(tài)性。

#include <iostream>
using namespace std;

class A {
public:
    virtual void Print() = 0;//純虛函數(shù)
    void func1() {
        cout << "A_func1" << endl;
    };
};

class B : public A {
public:
    void Print();
    void func1() {
        cout << "B_func1" << endl;
    };
};
void B::Print() {
    cout << "B_print" << endl;
};

int main() {
    //A a;           //?棕硫,抽象類不能實(shí)例化
    //A *pa = new A; //?髓涯,不能創(chuàng)建抽象類類A的示例
    //B b[2];        //?,不能聲明抽象類的數(shù)組

    A *pa;         //?哈扮,可以聲明抽象類的指針
    A *pb = new B; //使用基類指針指向派生類對(duì)象
    pb->Print();   //多態(tài)纬纪,調(diào)用的是類B中的函數(shù),B_print
    
    B b;
    A *pb1 = &b;
    pb1->func1();//不是虛函數(shù)滑肉,調(diào)用的是類A中的函數(shù)包各,A_func1
    
    return 0;
};

虛基類

定義虛基類的一般格式如下:

class 派生類名 : virtual 派生方式 基類名 {
    派生類體
};

多重繼承的模型結(jié)構(gòu)圖如下:

多重繼承

為了避免產(chǎn)生二義性,C++提供虛基類機(jī)制靶庙,使得在派生類中问畅,繼承同一個(gè)間接基類的成員僅保留一個(gè)版本。

#include <iostream>
using namespace std;

class A {
public:
    int a;
    void showa() {
        cout << "a = " << a << endl;
    };
};

class B : virtual public A {//對(duì)類A進(jìn)行了虛繼承
public:
    int b;
};

class C : virtual public A {//對(duì)類A進(jìn)行了虛繼承
public:
    int c;
};

class D : public B, public C {
//派生類D的兩個(gè)基類B六荒、C具有共同的基類A
//采用了虛繼承护姆,從而使類D的對(duì)象中只包含著類A的一個(gè)示例
public:
    int d;
};

int main() {
    D dObj;     //聲明派生類D的對(duì)象
    dObj.a = 11;//若不是虛繼承,這里會(huì)報(bào)錯(cuò)掏击!因?yàn)椤癉::a”具有二義性
    dObj.b = 22;
    
    dObj.showa();//a = 11
    //若不是虛繼承卵皂,這里會(huì)報(bào)錯(cuò)!因?yàn)椤癉::showa”具有二義性
    
    cout << "dObj.b = " << dObj.b << endl;//dObj.b = 22

    return 0;
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末砚亭,一起剝皮案震驚了整個(gè)濱河市灯变,隨后出現(xiàn)的幾起案子殴玛,更是在濱河造成了極大的恐慌,老刑警劉巖添祸,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滚粟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡膝捞,警方通過查閱死者的電腦和手機(jī)坦刀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔬咬,“玉大人,你說我怎么就攤上這事沐寺×炙遥” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵混坞,是天一觀的道長(zhǎng)狐援。 經(jīng)常有香客問我,道長(zhǎng)究孕,這世上最難降的妖魔是什么啥酱? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮厨诸,結(jié)果婚禮上镶殷,老公的妹妹穿的比我還像新娘。我一直安慰自己微酬,他們只是感情好绘趋,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著颗管,像睡著了一般陷遮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上垦江,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天帽馋,我揣著相機(jī)與錄音,去河邊找鬼比吭。 笑死绽族,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的梗逮。 我是一名探鬼主播项秉,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼慷彤!你這毒婦竟也來了娄蔼?” 一聲冷哼從身側(cè)響起怖喻,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岁诉,沒想到半個(gè)月后锚沸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涕癣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年哗蜈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坠韩。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡距潘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出只搁,到底是詐尸還是另有隱情音比,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布氢惋,位于F島的核電站洞翩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏焰望。R本人自食惡果不足惜骚亿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望熊赖。 院中可真熱鬧来屠,春花似錦、人聲如沸秫舌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽足陨。三九已至嫂粟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間墨缘,已是汗流浹背星虹。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留镊讼,地道東北人宽涌。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蝶棋,于是被迫代替她去往敵國(guó)和親卸亮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345