日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

类的6个默认成员函数:构造函数、析构函数、拷贝构造函数、重载运算符、三/五法则

發布時間:2023/12/13 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 类的6个默认成员函数:构造函数、析构函数、拷贝构造函数、重载运算符、三/五法则 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 6個默認成員函數
  • 構造函數
    • 概念
    • 默認構造函數的類型
    • 默認實參
      • 概念
      • 默認實參的使用
      • 默認實參聲明
      • 全局變量作為默認實參
    • 某些類不能依賴于編譯器合成的默認構造函數
      • 第一個原因
      • 第二個原因
      • 第三個原因
    • 構造函數初始化
      • 構造函數里面的“=”是初始化嗎?
      • 為什么要使用列表初始化?
      • 列表初始化
        • 成員初始化的順序
      • 類內成員的默認初始化
      • 賦值和初始化的效率差異
  • 拷貝構造函數
    • 概念
    • 拷貝構造函數的參數必須是引用類型
    • 編譯器合成的拷貝構造函數
    • 構造函數體內賦值和列表初始化的效率差異
      • 構造函數體內賦值
      • 列表初始化
      • 總結
    • 拷貝構造函數的兩種調用方式及易錯問題
      • 調用方式一
      • 調用方式二
      • 易錯問題
  • 重載運算符
    • 概念
    • ==運算符的重載
    • 賦值運算符的重載
      • 分清拷貝構造函數和賦值運算符
      • 注意
      • 實例
    • 取地址運算符重載、對const對象取地址運算符的重載
  • 析構函數
    • 概念
    • 構造函數和析構函數的類比
    • 怎樣調用析構函數
    • 下面代碼中會調用幾次析構函數?
    • 析構函數實例
  • =default
  • =delete
  • 三/五法則


6個默認成員函數

class Date { };

可以看到,上面那個類沒有任何成員,是一個空類,但是它真的什么都沒有嗎?

其實一個類在我們不寫的情況下,也會生成6個默認的成員函數,分別是:構造函數,析構函數,拷貝構造函數,賦值運算符重載,取地址運算符重載,對const對象取地址運算符的重載



構造函數

概念

特征:

  • 函數名與類名相同。
  • 無返回值。
  • 對象實例化時編譯器自動調用對應的構造函數。
  • 構造函數可以重載。
  • 不同于其他成員函數,構造函數不能被聲明成const的。
  • 不能被聲明成const的原因:

    構造函數的作用就是為了初始化對象的成員參數,如果被聲明為const則會認為自己無法修改調用對象的值,也就剝奪了構造函數的作用。

    但構造函數仍可以用來初始化const對象:

    當我們需要創建類的一個const對象時,直到構造函數完成初始化過程,對象才能真正取得其“常量”屬性(構造函數在進行初始化時對象的const屬性不生效)。因此,構造函數在const對象的構造過程中可以向其寫值,并且構造函數不必(實則不能)被聲明為const。


    默認構造函數的類型

    可分成兩類:

    • 編譯器合成的默認構造函數
    • 程序員定義的默認構造函數

    合成的默認構造函數按照如下規則初始化類的數據成員:

  • 如果存在類內的初始值,用它來初始化成員
  • 否則,默認初始化該成員
  • 如果我們要自己定義一個默認構造函數,那我們有兩種方法:

    1.定義一個無參的構造函數。
    2.定義所有參數都有缺省值(默認實參,在下面介紹)的構造函數【全缺省的構造函數】。

    在實際編程中,只能使用上述兩種方法中的一種,全缺省的構造函數和無參構造函數不能同時出現,因為編譯器會無法識別此時到底該調用哪一個。

    class Date { public://無參默認構造函數Date(){_year = 0;_month = 1;_day = 1;}//全缺省的默認構造函數Date(int year = 0, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//有參構造函數,也就是一般構造函數Date(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day; };int main() {Date d1;//調用默認構造函數Date d3();//如果要調用默認構造函數后面不能加上括號//加上了則變成了函數聲明Date d2(2020, 4, 19);//調用有參數的return 0; }

    默認實參

    概念

    默認實參:某些函數有這樣一種形參,在函數的很多次調用中它們都被賦予一個相同的值,此時我們把這個反復出現的值成為函數的默認實參

    默認實參作為形參的初始值出現在形參列表中。

    需要注意的是:

  • 我們可以為一個或多個形參定義默認值,但一旦某個形參被賦予了默認值,它后面的所有形參都必須有默認值。
  • 局部變量不能作為默認形參。
  • 類型可以轉化成形參所需類型的表達式也能作為默認實參。(比如函數的返回類型)
  • 第一點:

    class Date{Date(int year, int month = 1, int day)// error:一旦某個形參被賦予了默認值(month)// 它后面的所有形參都必須有默認值(day){_year = year;_month = month;_day = day;} };

    第二點:

    class Date{int i;Date(int year = i, int month = 1, int day = 1)// error:局部變量不能作為默認形參{_year = year;_month = month;_day = day;} };

    第三點:

    int sd();class Date { public:Date(int year = 0, int month = sd(), int day = 1)}

    默認實參的使用

    如果想使用默認實參,只要在調用函數時忽略該實參就行了。

    int main() {Date d2(2020); // 等價于d2(2020,1,1)return 0; }

    函數調用時實參按其位置解析,默認實參負責填補函數調用缺少的尾部實參(靠右側位置)。

    int main() {Date d2(,3,); // error:只能省略尾部實參return 0; }

    默認實參聲明

    通常的習慣是一個函數只聲明一次,但是實際上多次聲明同一個函數也是合法的。

    不過給定作用域中一個形參只能被賦予一次默認實參。換言之,函數的后續聲明只能為之前那些沒有默認值的形參添加默認實參

    而且同樣要遵循:該形參右側的所有形參必須都有默認值。

    Date(int year, int month, int day = 1)Date(int year, int month, int day = 2)// error:重復聲明Date(int year = 2, int month = 2, int day)// 正確

    全局變量作為默認實參

    //偽代碼 int i = 100, y =3; class Date { public:Date(int year = i, int month = y, int day = 1)// 用作默認實參的變量名在函數聲明所在的作用域內解析 }void fun() {i = 2020; // 改變默認實參的值int y = 4; //隱藏了外層定義的y,但沒有改變默認實參的值Date d = Date(); // 調用Date(2020,3,1)// 而變量名的求值過程發生在函數調用時 }
    • 其實就是fun中的 i 仍為全局變量,改變函數中的 i 就是改變 全局變量 i 。
    • 但是 函數中的 y 是生存期只在函數體內的局部變量,改變其值不影響全局變量 y 的值。

    某些類不能依賴于編譯器合成的默認構造函數

    第一個原因

    如果我們沒有顯式創建構造函數,編譯器會自動構建一個默認構造函數,但如果我們已經顯式定義了構造函數,則編譯器不會再生成默認構造函數。那么除非我們再定義一個默認的構造函數,否則類將沒有默認的構造函數。

    這條規則的依據是:如果一個類在某種情況下需要控制對象初始化(我們顯式定義構造函數),那么該類很可能在所有情況下都需要控制。


    第二個原因

    合成的默認構造函數可能執行錯誤的操作。如果定義在塊中的內置類型或復合類型(比如數組和指針)的對象被默認初始化,則他們的值將是未定義的。


    類中有其他類類型成員也一樣:

    如果真的非常想使用合成的默認構造函數又不想得到未定義的值,則可以將成員全部賦予類內的初始值,這個類才適合于使用編譯器合成的默認構造函數。

    第三個原因

    編譯器不能為有些類合成默認構造函數,例如,如果類中包含一個其他類類型的成員,且這個成員的類型沒有默認構造函數,那么編譯器將無法初始化該成員。


    從例子中可以看出,A類的構造函數可以正常工作,但是當使用Date類的合成默認構造函數創建一個對象時,由于Date類中有其他類類型的成員(A類型的成員a),且其所在類(A類)沒有默認構造函數(只有一般構造函數),導致編譯器無法初始化該成員(a)。


    構造函數初始化

    構造函數里面的“=”是初始化嗎?

    上面構造函數內的賦值語句是初始化嗎?

    乍一看很可能會覺得構造函數內的賦值語句是初始化,但是如果這樣寫呢?

    class Date { public:Date(int year, int month, int day){_year = year;_month = month;_day = day;_year = 2020;}int getyear(){return this -> _year;}private:int _year;int _month;int _day; };


    往后面加上了一個_year = 2020,那這樣還是初始化嗎?總不可能是先用year初始化_year,再用2020來初始化它,這明顯不成立,因為初始化只能一次,而函數體內的賦值可以多次, 所以我們可以將函數體內的賦值理解為賦初值,而非初始化。


    為什么要使用列表初始化?

    有時我們可以忽略數據成員初始化和賦值之間的差異,但并非總能這樣。

    當類的成員是以下三種時,必須通過構造函數初始值列表為它們提供初值(列表初始化):

  • 引用成員變量,引用必須在定義的時候初始化,并且不能重新賦值,所以也要寫在初始化列表中;
  • const成員變量,因為常量只能在初始化,不能賦值,所以必須放在初始化列表中;
  • 未提供默認構造函數的類類型,因為使用初始化列表可以不必調用默認構造函數來初始化,而是直接調用拷貝構造函數;
  • 通過一個例子來理解1、2點的意思:

    • 隨著構造函數體一開始執行,初始化就完成了
    • 初始化完成了也就意味著只能進行賦值操作了,不能進行定義且賦值的操作了。
    • 不能賦值的成員(const屬性、引用類型)如果沒有在此之前完成初始化過程也就成為了未定義的狀態。例如下面的:_month的const屬性已經成立,無法再在函數體內為_month賦值了;_day是引用類型,沒有進行初始化的引用類型是無法賦值的。

    而我們上面說過,構造函數里面的“=”是賦值行為而非初始化,因此:

    class Date { public:Date(int i) {_year = i; // 正確_month = i; // 錯誤:不能給const賦值_day = i; // 錯誤:i沒被初始化}private:int _year;const int _month;int &_day; };

    因此我們初始化const或者引用類型的數據成員的唯一機會就是 通過構造函數初始值列表為它們提供初值。


    列表初始化

    class Date { public:// 列表初始化Date(int& year, const int month, int day):_year(year),_day(day),_month(month){}int getye(){return this -> _year;}int getmoth(){return this -> _month;}int getday(){return this -> _day;}private:int &_year;const int _month;int _day; }; int main(int argc, char const *argv[]) {int i = 2020;Date a(i,3,14);cout << a.getye() << endl;cout << a.getmoth() << endl;cout << a.getday() << endl;return 0; }

    成員初始化的順序

    列表初始化中有一個容易出錯的地方——成員初始化的順序,可以看到,我這里初始化列表的順序是year,day,month。但是實際上初始化的順序和初始化列表中順序毫無關聯,初始化的順序是按照參數在類中聲明的順序的, 也就是下面的year,month,day(如圖)。

    一般來說,初始值列表的初始化順序不會影響什么,就如上面的代碼,結果依然符合我們的預期:

    不過如果一個成員是用另一個成員來初始化的,那么這兩個成員的初始化順序就很關鍵了,具體是什么意思呢?舉個例子,將初始值列表做出如下更改:

    Date(const int& year, const int month):_year(year),_day(month),_month(_day){}

    查看結果:

    int main() {int i = 2020;Date d2(i, 4);cout << d2.getmoth() << endl;cout << d2.getday() << endl;return 0; }

    形式上初始值列表的順序來講:

  • 先用形參month初始化成員_day
  • 再用初始化成功的_day去初始化成員_month
  • 但實際上真的是這樣嗎? 我們來看看運行結果:


    可以看到初始化成功的只有成員_day,實際上,初始化的順序是按照參數在類中的聲明順序來的:

  • 也就是先用形參year初始化成員_year
  • 再用成員_day初始化成員_month但由于此時成員_day尚未被形參month初始化,因此成員_month值是未定義的。
  • 接下來用形參month初始化成員_day
  • 從而生成了上圖的結果。


    類內成員的默認初始化

    如果沒有在構造函數的初始值列表中顯式地初始化成員,則該成員會在構造函數體之前執行默認初始化。

    執行默認初始化分兩種情況:

    第一種,被忽略的成員有類內初始值(本例中的_month,_day):

    class Date { public:Date(int year):_year(year){ }int getye(){return this -> _year;}int getmoth(){return this -> _month;}int getday(){return this -> _day;}private:int _year;int _month = 3;int _day = 24; }; int main(int argc, char const *argv[]) {Date a(2020);cout << a.getye() << endl;cout << a.getmoth() << endl;cout << a.getday() << endl;return 0; }


    從結果可知,沒有在初始值列表中顯式初始化的數據成員,如果其具有類內初始值,會隱式地使用類內初始值初始化。

    第二種情況,被忽略的成員沒有類內初始值(本例中的_month,_day):

    class Date { public:Date(int year):_year(year){ }int getye(){return this -> _year;}int getmoth(){return this -> _month;}int getday(){return this -> _day;}private:int _year;int _month;int _day; }; int main(int argc, char const *argv[]) {Date a(2020);cout << a.getye() << endl;cout << a.getmoth() << endl;cout << a.getday() << endl;return 0; }


    從結果可知,沒有在初始值列表中顯式初始化的數據成員,如果其也沒有類內初始值,則其值是未定義的,試圖拷貝或以其他形式訪問此類值將引發錯誤。

    綜述:

  • 構造函數不應該輕易覆蓋掉類內初始值,除非新賦的值與原值不同。
  • 構造函數使用類內初始值不失為一種好的選擇,因為這樣能確保為成員賦予了一個正確的值。
  • 如果不能使用類內初始值(編譯器不支持或其他原因),則所有構造函數都應該顯式地初始化每一個內置類型的成員。

  • 賦值和初始化的效率差異

    很多類中,賦值和初始化的區別事關底層效率問題(對于內置類型而言賦值和初始化在效率上的區別不是很大):

    • 賦值首先會用默認構造函數來構造對象,再通過重載后的賦值運算符進行賦值。
    • 列表初始化會直接調用拷貝構造函數,減少了一次調用默認構造函數的時間。

    具體詳解在下面的拷貝構造函數中。



    拷貝構造函數

    概念

    如果構造函數的

    • 第一個參數是自身類類型的引用
    • 其他參數(如果有的話)都有默認值。

    則此構造函數是拷貝構造函數。

    拷貝構造函數賦值運算符重載是C++為我們準備的兩種能夠通過其他對象的值來初始化另一個對象的默認成員函數

    拷貝構造函數是構造函數的一個重載形式

    Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}

    調用方法,用別的對象來為本對象賦值,同時因為不需要修改引用的對象則為它加上const屬性。

    int main() {Date d1;Date d2 = d1;Date d3(d1);//這兩種等價,都是拷貝構造函數,并且d2不是賦值運算符重載 }

    拷貝構造函數的參數必須是引用類型

    原因如下:

    函數具有以下特性:

    • 函數調用過程中,非引用類型的參數需要進行拷貝初始化。
    • 函數具有非引用的返回類型時,返回值會被用來初始化調用方的結果。

    根據上述特性可知:

  • 拷貝構造函數被用來初始化函數的非引用類類型參數
  • 如果拷貝函數本身的參數不是引用類型,為了調用拷貝構造函數,我們必須拷貝他的實參,為了拷貝實參,又需要調用拷貝構造函數,如此無限循環。
  • 以本例來講:

    當我們要用d1來初始化d2的時候,需要將d1先傳遞給形參d,再用形參d進行賦值,但是d1傳遞給d的時候又會再次調用一個拷貝構造函數,這個d又會給它的拷貝構造函數的形參d傳參,這又會調用新的拷貝構造函數,就導致了一個無限循環, 所以要加上引用。

    編譯器合成的拷貝構造函數

    如果我們不去定義一個拷貝構造函數,編譯器也會默認創建一個。默認的拷貝構造函數對象按內存存儲按字節序完成拷貝, 這種拷貝我們叫做淺拷貝,或者值拷貝。 如果是上面這個日期類,當然沒問題,但如果涉及到了動態開辟的數據,就會有問題了。

    假設在堆上開辟了某個大小的一個數據,默認的拷貝構造函數會按照字節序來拷貝這個數據,這一步其實沒問題,問題就出在析構函數上。因為析構函數會在類的生命周期結束后將類中所有成員變量釋放,這時淺拷貝的數據就會存在問題,因為他們指向的是同一塊空間

    (合成拷貝構造函數做的是用別的對象來為本對象賦值,對于別的對象動態開辟的空間只是創建一個指針再指向那個空間,而非用new再開辟一個新空間,此時就出現了多個指針指向同一個空間的情況)

    而原對象和拷貝的對象會分別對它釋放一次,就導致了重復釋放同一塊內存空間(double free)

    所以對于動態開辟的數據,我們需要使用深拷貝

    構造函數體內賦值和列表初始化的效率差異

    代碼如下:

    class A{int test = 666; public:A(int i):test(i){cout << "a列表初始化" << endl;}A(){cout << this << endl;cout << "a默認構造函數" << endl;cout << endl;}A(const A& a2){test = a2.test;cout << "調用者 " << this << endl;cout << "被調用者 " << &a2 << endl;cout << "a拷貝構造函數" << endl;cout << endl;}A& operator=(const A& a4){cout << "調用者: " << this << endl;cout << "被調用者: " << &a4 << endl;cout << "a賦值運算符重載" << endl;if(this != &a4){test = a4.test;}return *this;}int gett(){return this->test;}~A(){cout << "a析構函數 " << this << endl;} };class Date { public:Date(int year, int month, int day, A a1)//構造函數{cout << "執行函數體前" << endl;_year = year;_month = month;_day = day;_a = a1;cout << endl;cout << "成員_a " << &_a << endl;cout << "a1 " << &a1 << endl;cout << "d構造函數 " << endl;}Date(int flag,A a3):_year(flag), _month(flag), _day(flag), _a(a3){cout << "a3: " << &a3 << endl;cout << "_a: " << &_a << endl;cout << "d列表初始化" << endl;}Date(){cout << this << endl;cout << "d默認構造函數" << endl;}Date(const Date& d){cout << "before" << endl;_year = d._year;_month = d._month;_day = d._day;_a = d._a;cout << endl;cout << "_a: " << &_a << endl;cout << "d._a: " << &d._a << endl;cout << "d拷貝構造函數" << endl;}Date& operator=(const Date& d){if(this != &d){_year = d._year;_month = d._month;_day = d._day;_a = d._a;}cout << "調用者: " << this << endl;cout << "被調用者: " << &d << endl;cout << "d賦值運算符重載" << endl;return *this;}~Date(){ cout << "d析構函數 " << this << endl; }private:int _year = 2001;int _month = 13;int _day = 250;A _a; };

    兩者運行結果如下:

    構造函數體內賦值

    int main() {A a;// 調用有參構造函數cout << "d1:" << endl;Date d1(2021,3,20,a);cout << endl;return 0; }


    從d1的運行結果可知,我們進行構造函數體內賦值操作時,

  • 編譯器在調用d的構造函數之前(執行d的構造函數體之前),首先調用A的拷貝構造函數,用實參a初始化a1(d構造函數的形參)。
  • 然后調用A的默認構造函數創建數據成員_a。
  • 創建好數據成員_a之后,開始執行b的構造函數函數體(即調用b的構造函數),使用A的重載賦值運算符將a1的值賦給數據成員_a。
  • 執行完d1的構造操作后,編譯器調用a的析構函數,釋放之前創建的形參a1。
  • 列表初始化

    int main() {A a;// 調用列表初始化的構造函數cout << "d5:" << endl;Date d5(888,a); }


    而對比d5的運行結果可知,我們進行列表初始化時,編譯器兩次調用拷貝構造函數,

  • 一次用實參a初始化形參a3。
  • 一次用形參a3初始化數據成員_a。
  • 之后執行a的析構函數,釋放創建的形參a3。
  • 總結

    列表初始化的第2點在函數體內賦值中被拆分成了2、3點。換言之,默認構造函數、重載的賦值運算符兩步完成的操作 與 拷貝構造函數一步完成的操作是等價的,而我們說過

    拷貝構造函數和賦值運算符重載是C++為我們準備的兩種能夠通過其他對象的值來初始化另一個對象的默認成員函數。

    它們起到的功能是一樣的,因此我們說減少了一次調用默認構造函數的時間。

    拷貝構造函數的兩種調用方式及易錯問題

    調用方式一

    int main() {A a;// 調用拷貝構造函數的方式一cout << "d2:" << endl;Date d2(d1);cout << endl; }

    調用方式二

    int main() {A a;//調用拷貝構造函數的方式二cout << "d4:" << endl;Date d4 = d1;cout << endl; }

    可以發現兩種調用方式執行的底層操作都是一樣的:

    1. 函數聲明階段,也就是執行拷貝構造函數函數體之前(圖中的before之前),調用a的默認構造函數創建數據成員_a
    2. 執行函數體,用被調用的Date類(d1)初始化調用的Date類(d2,d4),(執行到數據成員_a的初始化時,用A的重載賦值運算符將d._a賦給_a)

    易錯問題

    但是如以下形式的代碼,看起來類似第二種調用方式,但其實不然:

    int main() {A a;cout << "d3:" << endl;Date d3;cout << "賦值之前" << endl;d3 = d1;cout << endl; }


    其執行步驟如下:

    1. 先用默認構造函數創建d3(創建類內數據成員_a時調用A的默認構造函數)
    2. 再使用重載賦值運算符進行賦值(為類內數據成員_a賦值時調用A的重載賦值運算符)

    區別:
    粗略理解的話,就是兩者一個是由拷貝構造函數直接創建對象(d2,d4),一個是用默認構造函數創建對象(d3)之后再用重載賦值運算符進行賦值。類比內置類型的初始化和定義再賦值可能更便于理解。



    重載運算符

    類的賦值運算符實際上是對賦值運算符的重載,因此我們先介紹一下重載運算符。

    概念

    函數原型:

    返回值類型 operator操作符(參數列表)

    關于重載運算符:

  • 某些運算符(如賦值運算符)必須定義為成員函數。
  • 如果一個運算符是一個成員函數,其左側運算對象就綁定到隱式的 this 參數。
  • 規則:

    • 不能通過連接其他符號來創建新的操作符:比如operator@
    • 重載操作符必須有一個類類型或者枚舉類型的操作數
    • 用于內置類型的操作符,其含義不能改變,例如:內置的整型+,不 能改變其含義
    • 作為類成員的重載函數時,其形參看起來比操作數數目少1,成員函數的操作符有一個默認的形參this,限定為第一個形參
    • :: 、*、?、: 、. 注意以上5個運算符不能重載。

    通常情況下,不應該重載逗號、取地址、邏輯與和邏輯或運算符。

    選擇重載運算符作為成員函數or非成員函數是很重要的

    • 賦值(=)、下標([ ])、調用(())和成員訪問箭頭(->)運算符必須是成員。
    • 復合賦值運算符一般來說應該是成員,但并非必須,這一點與賦值運算符略有不同。
    • 改變對象狀態的運算符或者與給定類型密切相關的運算符,如遞增、遞減和解引用運算符,通常應該是成員。
    • 具有對稱性的運算符可能轉換任意一端的運算對象,例如算術、相等性、關系和位運算符等,因此它們通常應該是普通的非成員函數。

    什么叫對稱性運算符?其實就是形如 + 這樣的 int + double 和 double + int 是一樣的。

    如果對稱性運算符是成員函數呢?假設 operator+ 是 string類 的成員(實際上是非成員):

    • operator+ 是 string類 的成員,上面的第一個加法等價于 s.operator+("!")。
    • "hi"+s 等價于 "hi".operator+(s) 。"hi" 的類型是 const char*,這是一種內置類型,內置類型根本就沒有成員函數。

    因為 string 將 + 定義成了普通的非成員函數,所以 "hi"+s 等價于 operator+("hi",s) 。和任何其他函數調用一樣,每個實參都能被轉換成形參類型**。唯一的要求是至少有一個運算對象是類類型**,并且兩個運算對象都能準確無誤地轉換成 string。

    ==運算符的重載

    //成員函數的操作符重載bool operator==(const Date& d2){return _year == d2._year&& _month == d2._month&& _day == d2._day;}//如果寫成普通的函數bool operator==(const Date& d1, const Date& d2) {return d1._year == d2._year&& d1._month == d2._month&& d1._day == d2._day; }int main() {bool isSame = (d1 == d2)//調用時等價于 isSame = d1.operator==(d2);//或者 isSame = operator==(d1, d2); }

    賦值運算符的重載

    分清拷貝構造函數和賦值運算符

    上面說過,有兩種方法能夠實現用其他類來拷貝一個類,一個是拷貝構造函數,一個是賦值運算符重載

    int main() {Date d;Date d1(d);Date d2 = d;//在聲明的時候初始化,用d初始化d2,調用的是拷貝構造函數d1 = d2;//是在對象d1已經存在的情況下,用d2來為d1賦值,這才是賦值運算符重載//聲明階段的“=”都自動調用了拷貝構造函數,只有不是聲明階段的“=”才是賦值運算符重載return 0; } Date& operator=(const Date& d){if(this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}

    注意

    需要注意的有幾點

  • 返回 *this。原因有兩點:
    • 避免了返回非引用所需的拷貝操作,提高效率;
    • 當出現形如這樣的操作時:(a=b)=c,如果返回類型不是引用,則對括號內 a=b 得到的結果進行一次拷貝初始化,得到一個匿名對象(臨時對象),這個匿名對象是一個右值,對其進行=c的賦值操作是未定義行為。
  • 檢測是否是自己給自己賦值,如果是則忽略
  • 因為不需要修改任何參數,所以參數都需要加上const,并且為了不花費多余的空間去拷貝數據,都采取引用
  • 一個類如果沒有顯式定義賦值運算符重載,編譯器也會生成一個,完成對象按字節序的值拷貝
  • 實例

    舉一個包含指針成員的類的重載賦值運算符該怎么寫的例子:

    class A { public:A(const string &s = string()):ps(new string(s)){ }A& operator=(const A&);void getps() {cout << ps << endl;}private:int i = 0;string* ps; };A& A::operator=(const A& a) {string* newps = new string(*a.ps);cout << *a.ps << endl;cout << a.ps << endl;// 拷貝指針指向的對象// 不加解引用符就成了拷貝指針本身delete ps; // 銷毀ps指向的內存,避免內存泄漏ps = newps; // 將newps指向的內存賦給ps// newps和ps現在指向同一塊內存i = a.i;return *this; // 返回此對象的引用 } int main() {A a;string s1 = "hello";A a1(s1);a = a1; }

    輸出結果:

    下面思考一個問題

    A& A::operator=(const A& a) {string* newps = new string(*a.ps);delete ps; // 銷毀ps指向的內存,避免內存泄漏ps = newps; i = a.i;return *this; // 返回此對象的引用 }A& A::operator=(const A& a) {delete ps; // 銷毀ps指向的內存,避免內存泄漏ps = new string(*(a.ps)); i = a.i;return *this; // 返回此對象的引用 }

    為什么我們先將 a.ps 拷貝到一個局部臨時對象中(newps),然后銷毀 *this的ps (釋放舊內存),再將 newps 賦值給 *this.ps ?而不是像第二種寫法那樣先釋放舊內存,再直接將 a.ps 拷貝給 *this.ps ?

    這是因為如果 a 和 *this 是 同一個對象,delete ps 會釋放 *this 和 a 指向的 string。接下來,當我們在 new表達式 中試圖拷貝*(a.ps)時,就會訪問一個指向無效內存的指針,其行為和結果是未定義的。

    示例中的 A類 在 《C++Primer》中也被稱為行為像指針的類,這個概念我將在另一篇博客中細講。


    取地址運算符重載、對const對象取地址運算符的重載

    取地址運算符也有兩個默認的成員函數,編譯器默認生成,不需要我們定義,一般只有想讓別人獲取指定內容的時候才自己定義一個。

    class Date { public:Date(int year = 0, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//默認取地址重載Date* operator&(){return this;}//const取地址重載const Date* operator&()const{return this;}int _year;int _month;int _day; };

    析構函數

    概念

    析構函數也是一個特殊的成員函數,它的功能是:

  • 釋放對象在生存期分配的的所有資源
  • 銷毀對象的非static數據成員
  • 特征:

    • 析構函數名是在類名前加上字符 ~。
    • 無參數無返回值。
    • 因為不接受參數因此不能被重載。
    • 一個類有且只有一個析構函數。若未顯式定義,系統會自動生成默認的析構函數。
    • 對象生命周期結束時,C++編譯系統系統自動調用析構函數

    構造函數和析構函數的類比

  • 構造函數有一個初始化部分和一個函數體。
  • 析構函數有一個析構部分和一個函數體。
  • 構造函數中,成員初始化是在函數體執行之前完成的,按照在類中出現的順序進行初始化
  • 析構函數中,首先執行函數體,然后銷毀成員。 成員按照初始化順序的逆序銷毀
  • 邏輯上:

    • 析構函數體一般負責銷毀對象引用的內存(持有的資源)
    • 析構部分則是負責對象本身成員的析構
    • 析構部分會逐個調用類類型成員的析構函數(調用順序與聲明順序相反),除此之外,析構部分還負責調用父類析構函數。

    實現上:

    • 只有析構函數體是對程序員可見的,析構部分是隱式的。
    • 所謂隱式的,是指這部分代碼(即調用類成員析構函數和父類析構函數的代碼)是由編譯器合成的。
    • 成員銷毀時發生什么完全依賴于成員的類型:銷毀類類型的成員需要執行成員自己的析構函數。內置類型沒有析構函數,因此銷毀內置類型成員什么也不需要做。

    銷毀普通指針和銷毀智能指針的不同:

    關于智能指針的知識在這里

    基于上述紅字部分:

    • 隱式銷毀一個內置指針類型的成員不會delete它所指向的對象。也就是要格外注意類內指針的釋放,避免內存泄漏
    • 與普通指針不同,智能指針是類類型,所以具有析構函數。因此,智能指針成員在析構階段會被自動銷毀。

    怎樣調用析構函數

    無論何時一個對象被銷毀,就會自動調用其析構函數:

    • 變量在離開其作用域時被銷毀。
    • 當一個對象被銷毀時,其成員被銷毀。
    • 容器(無論是標準庫容器還是數組)被銷毀時,其元素被銷毀。
    • 對于動態分配的對象,當對指向它的指針應用delete運算符時被銷毀。
    • 對于臨時對象,當創建它的完整表達式結束時被銷毀。

    具體如下:

    當指向一個對象的引用或指針離開作用域時,析構函數不會執行。 因此上述代碼唯一需要直接管理的內存就是直接分配的Sales_data對象,只需要直接釋放綁定到 p 的動態分配對象。


    下面代碼中會調用幾次析構函數?


    這段代碼中會發生三次析構函數調用:

  • 函數結束時,局部變量item1的生命期結束,被銷毀,Sales_data的析構函數被調用。
  • 類似的,item2在函數結束時被銷毀,Sales_data的析構函數被調用。
  • 函數結束時,參數accum的生命期結束,被銷毀,Sales_data的析構函數被調用。
  • 在函數結束時,trans的生命期也結束了,但并不是它指向的Sales_data對象的生命期結束(只有delete指針時,指向的動態對象的生命期才結束),所以不會引起析構函數的調用。


    析構函數實例

    class A { public:A(const char* str = "hello world", int num = 3){_str = (char*)malloc(sizeof(str));strcpy(_str, str);_num = num;cout << "constructor function" << endl;}~A(){free(_str);_str = nullptr;_num = 0;cout << "destructor function" << endl;}char* getstr(){return this->_str;}int getnum(){return this->_num;} private:char* _str;int _num; }; int main(int argc, char const *argv[]) {A a = A();cout << a.getstr() << endl;cout << a.getnum() << endl;return 0; }

    從結果可以看到,析構函數的執行在return語句之前。



    =default

    可以通過使用 =default 來顯式的要求編譯器生成合成的拷貝控制成員函數。
    但值得注意的是:

  • 當我們在類內用=default修飾成員的聲明時,合成的函數將隱式地聲明為內聯的,就像任何其他類內聲明的成員函數一樣。
  • 如果我們不希望合成的成員是內聯函數,應該只對成員的類外定義使用=default,就像對拷貝賦值運算符所做的那樣。
  • =delete

    雖然大部分情況下都需要拷貝構造函數和拷貝賦值運算符,但是對于某些類來講,這些操作沒有合理的意義,此時應該使用 =delete 將無意義的操作定義為刪除的函數。其含義是:雖然該函數被定義,但無法被使用。如:iostream類阻止了拷貝,以避免多個對象寫入或讀取相同的IO緩沖。

    struct A{A() = default; // 使用合成的默認構造函數A(const A&) = delete; // 阻止拷貝A &operator=(const A&) = delete; // 阻止賦值 };

    與=default不同,=delete必須出現在函數第一次聲明的時候。

  • 從邏輯上講,默認的成員只影響為這個成員而生的代碼,因此=default直到編譯器調用默認成員時才需要。
  • 而編譯器需要在第一時間知道一個函數是刪除的,以便禁止試圖使用它的操作。
  • 兩者另一個不同之處是,我們可以對任何函數指定=delete,但是只能對編譯器可以合成的函數(默認構造函數或拷貝控制成員)使用=default。

    在舊標準中我們用聲明成private但不定義的方法來起到新標準中 =delete 的作用,此時試圖使用該種函數的用戶代碼將在編譯階段被標記為鏈接錯誤。



    三/五法則

    由于拷貝控制操作是由三個特殊的成員函數來完成的:

  • 拷貝構造函數定義了當用同類型的另一個對象初始化新對象時做什么
  • 拷貝賦值運算符定義了將一個對象賦予同類型的另一個對象時做什么
  • 析構函數定義了此類型的對象銷毀時做什么。
  • 所以我們稱此為“C++三法則”。在較新的 C++11 標準中,為了支持移動語義,又增加了移動構造函數和移動賦值運算符,這樣共有五個特殊的成員函數,所以又稱為“C++五法則”。也就是說,“三法則”是針對較舊的 C++89 標準說的,“五法則”是針對較新的 C++11 標準說的。為了統一稱呼,后來人們把它叫做“C++ 三/五法則”。

  • 需要析構函數的類也需要拷貝構造函數和拷貝賦值運算符。
    從“需要析構函數”可知,類中必然出現了指針類型的成員(否則不需要我們寫析構函數,默認的析構函數就夠了,一般是內置指針類型,類類型的話一般直接調用該類的析構函數,不用我們自己再實現一個析構函數),所以,我們需要自己寫析構函數來釋放給指針所分配的內存來防止內存泄漏。
    那么為什么說“也需要拷貝構造函數和賦值操作”呢?原因是:類中出現了指針類型的成員這樣的外部資源,合成的拷貝構造函數和合成的拷貝賦值運算符是對外部資源的淺拷貝,因此析構函數執行delete運算符時會出現double free的錯誤。
  • 拷貝構造函數和拷貝賦值運算符要么都是合成版本,要么都是自定義版本。
    拷貝構造函數用已有對象構造新對象,函數體內類成員的構造方法就是利用拷貝賦值運算符。
  • 析構函數不能是刪除的,否則便無法銷毀此類型的對象了。
    同時,編譯器不允許定義該類型的變量或創建該類的臨時對象。可以動態分配該對象并獲得其指針,但無法銷毀這個動態分配的對象(delete 失效)。
  • 如果一個類有私有的或不可訪問的析構函數,那么其默認和拷貝構造函數會被定義為私有的。
  • 如果一個類有const或引用成員,則不能使用默認的拷貝賦值操作。
    原因很簡單,const或引用成員只能在初始化時被賦值一次,而默認的拷貝賦值操作會對所有成員都進行賦值。顯然,它不能賦值const和引用成員,所以默認的拷貝構造函數不能被使用,即會被定義為私有的。
  • //關于第三點的代碼 struct A{A() = default;~A() = delete; }; A a; //ERROR:A的析構函數是刪除的。 A *p = new A(); //正確:但無法delete p; delete p; // ERROR:A類沒有析構函數,無法釋放指向A類動態分配對象的指針。

    總結

    以上是生活随笔為你收集整理的类的6个默认成员函数:构造函数、析构函数、拷贝构造函数、重载运算符、三/五法则的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    欧美日韩综合在线观看 | 国产精品高潮呻吟久久久久 | 午夜12点 | 亚洲不卡av一区二区三区 | 夜夜爽88888免费视频4848 | 97精品在线 | 99精彩视频 | 久草久| 久久免费影院 | 五月天婷婷在线观看视频 | 欧美日韩视频一区二区三区 | 午夜免费福利视频 | 日本久久视频 | 日韩精品中文字幕在线 | 久久精品久久精品久久精品 | 国产精品久久久久久久午夜片 | 三级av免费看 | 美女黄久久 | 福利视频在线看 | 五月婷在线观看 | 亚欧日韩av| 日韩av影视 | av国产在线观看 | 成人av资源网站 | 91高清视频| 精品国自产在线观看 | 亚洲精品中文在线观看 | 亚洲一级影院 | 成人黄色在线视频 | 亚洲成人精品在线观看 | 久久久久99精品成人片三人毛片 | 国产精品美女在线 | 久久伊人精品天天 | 欧美一区二区精品在线 | 人人爽久久涩噜噜噜网站 | 91视频高清| 精品美女久久久久久免费 | 午夜视频在线观看一区二区三区 | 在线观看精品视频 | 中文字幕一区二区三区乱码在线 | 黄色三级免费观看 | 激情欧美网 | 精品在线观看国产 | 国内精品免费 | 五月天久久狠狠 | 国产精品免费视频一区二区 | 免费高清在线视频一区· | 五月开心网 | 久在线观看 | 日韩视频www | 久久99热这里只有精品 | 欧美日韩免费在线视频 | 久久人91精品久久久久久不卡 | av黄色影院 | a在线观看国产 | 国产香蕉在线 | 亚洲欧美国产日韩在线观看 | 激情开心| 国产视频久久久 | 人人舔人人爽 | 99这里精品 | 在线免费视频a | 草久久av | 中文字幕一区二区在线观看 | 亚洲国产成人精品电影在线观看 | 日韩高清在线一区二区三区 | 97视频在线 | 色婷婷激情四射 | av中文资源在线 | 国产女做a爱免费视频 | 国产精品一区二区在线看 | 日本久久久久久科技有限公司 | 在线观看成年人 | 欧美一区三区四区 | 一区二区不卡视频在线观看 | 美女视频黄免费的 | 四川bbb搡bbb爽爽视频 | 日韩欧美综合在线视频 | 久草香蕉在线视频 | 四虎影视精品永久在线观看 | av成人免费网站 | 午夜免费电影院 | 91男人影院| 久久久久女人精品毛片 | 密桃av在线 | 精品日韩视频 | 久久国产精品一国产精品 | 97激情影院 | 国产色网站 | 日产乱码一二三区别在线 | 全黄色一级片 | 欧美一区日韩一区 | 中文字幕在线免费观看 | 99精品在线视频播放 | 国产91国语对白在线 | 免费看片网址 | 午夜免费电影院 | 欧美一级片在线观看视频 | 激情偷乱人伦小说视频在线观看 | 三级黄色免费 | 欧美色图88 | 黄色软件视频大全免费下载 | 色婷婷视频网 | a午夜电影 | 免费看黄的视频 | 91伊人影院 | 欧美日韩精品在线免费观看 | 国产成人精品久久久久蜜臀 | 黄色a视频 | 日韩毛片在线一区二区毛片 | 一区二区精品在线观看 | 麻豆免费视频观看 | 一区二区欧美激情 | av五月婷婷 | 亚洲精品9| 免费在线看v | 在线黄色av电影 | 日本精品在线 | 久草99| 又湿又紧又大又爽a视频国产 | 中文字幕日韩电影 | 欧美精品免费一区二区 | 国产黄色特级片 | 日日日日日 | 在线播放 日韩专区 | 又黄又爽又色无遮挡免费 | 91精品一区二区三区蜜臀 | 国产特黄色片 | 国产一区在线播放 | 久久久久国产视频 | 人人操日日干 | 91亚洲狠狠婷婷综合久久久 | 碰超在线观看 | 婷婷丁香激情网 | 天天曰视频 | 懂色av一区二区三区蜜臀 | 国产艹b视频 | 高清av免费一区中文字幕 | 国产精品二区三区 | 亚洲精品美女久久久久 | 97视频人人免费看 | 国产一区高清在线 | 国产九九热视频 | 欧美日韩视频一区二区三区 | 欧美日韩免费一区二区 | 欧美福利网址 | 韩国av一区二区三区在线观看 | 日本精品视频一区 | 永久免费视频国产 | 91黄色视屏 | 国产精品久久久久免费观看 | 日韩精品中文字幕有码 | 亚洲成人在线免费 | 国产在线观看污片 | 性色av一区二区 | 天天天天干 | 欧美一区二区三区在线看 | 特级西西444www高清大视频 | 在线观看中文字幕网站 | 天天爽天天爽夜夜爽 | 97电影手机版 | 干综合网 | 国产一区二区三区免费观看视频 | 久草视频免费看 | 日韩女同一区二区三区在线观看 | 狠狠色丁香九九婷婷综合五月 | 成人动图 | 天堂网一区二区 | 激情综合六月 | 国产精品成人在线观看 | 香蕉久久久久久av成人 | 四虎影视精品永久在线观看 | 国产日产在线观看 | 久久国产精品视频观看 | 国产精品美女久久久久久久久 | 亚洲国产视频直播 | 国产精品一级视频 | 久久久黄色av | 国产精品视频专区 | 欧美在线观看禁18 | 国产精品第7页 | 久久a v电影 | 精品国产一区二区三区在线观看 | 欧美韩日精品 | 一区二区三区在线影院 | 最新av网址在线观看 | 欧美日韩首页 | 九九精品无码 | 国产精品国产三级在线专区 | 亚洲天天摸日日摸天天欢 | 免费日韩视 | 久久激五月天综合精品 | 日韩免费一区二区在线观看 | 99久热在线精品视频 | 97成人在线观看 | 亚洲国产日韩欧美在线 | 久久精品视频5 | 国产精品女视频 | 午夜电影久久久 | 亚洲视频综合 | 国产视频一二三 | 国产精品入口传媒 | 一本一道久久a久久精品 | 国产日韩在线看 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 日韩高清黄色 | 久久观看最新视频 | 98超碰在线 | 欧美 日韩 性 | 天天操天天射天天舔 | 亚洲精品麻豆视频 | 亚洲婷婷综合色高清在线 | 国产精品18毛片一区二区 | 玖草影院 | 丁香六月婷 | 国产精品美女999 | 欧美a免费 | 欧美日韩国产高清视频 | 国产精品 中文字幕 亚洲 欧美 | av导航福利| 看片的网址 | 精品国产一区二区三区在线观看 | 91精品国产欧美一区二区成人 | 免费观看的黄色片 | 中文免费| 免费又黄又爽视频 | 欧美另类亚洲 | 中文字幕在线观看第一页 | 日韩欧美久久 | 欧美性色综合网站 | 色视频网站在线观看一=区 a视频免费在线观看 | 成人av影视观看 | 亚洲日本国产精品 | 美女视频黄是免费的 | 亚洲激情在线播放 | 欧美久久久一区二区三区 | 99久久精品日本一区二区免费 | 久99久视频 | 最新在线你懂的 | 国产视频九色蝌蚪 | 综合久久久久久久久 | 激情五月综合 | 欧美日韩18 | 青草草在线视频 | 久久久久久久久久福利 | 精品毛片久久久久久 | 在线看片一区 | 亚洲最大成人免费网站 | 天天综合网在线 | 久久看毛片 | 中文字幕视频观看 | 男女靠逼app | 久久天天躁夜夜躁狠狠躁2022 | aav在线 | 美女久久| 男女精品久久 | 97精品国产97久久久久久免费 | 久久一线| 免费观看的av网站 | 久久国产精品电影 | 国产精品福利久久久 | 成人网在线免费视频 | 日韩一区二区三区视频在线 | 成年人黄色免费看 | 久久这里只有精品首页 | 一二区精品 | 99这里只有精品99 | 在线 高清 中文字幕 | 成人av免费在线 | 午夜的福利 | 午夜电影av | 亚洲精品小区久久久久久 | 人人干在线观看 | 久久99视频免费观看 | 亚洲国产精品一区二区久久,亚洲午夜 | 色婷婷免费视频 | 一二三区在线 | 日韩欧美一区视频 | 日日夜夜艹 | 成人一区二区三区在线观看 | 国产精品18久久久久久久 | 中文理论片 | 超碰在97 | 亚洲欧美日韩一二三区 | 五月婷婷播播 | 天天爽人人爽 | 97在线观看免费视频 | 91大神电影 | 国产小视频精品 | 国产高清在线永久 | 久久久久久久久久影院 | 91在线视频网址 | 久久精品国产精品 | 中文字幕亚洲综合久久五月天色无吗'' | 在线观看黄 | 中文字幕在线观看网 | 久久亚洲综合色 | 成人久久免费 | 久久久久亚洲精品男人的天堂 | 亚洲精品在线观看不卡 | 国产在线999| 天天做天天干 | 干干干操操操 | 中文字幕中文 | a在线免费| 91系列在线观看 | 激情综合网天天干 | 91九色最新 | 免费97视频 | 亚洲乱亚洲乱亚洲 | 黄色三级免费观看 | 在线a视频 | 十八岁以下禁止观看的1000个网站 | 国产精彩视频一区 | 欧美日韩国产精品一区二区亚洲 | 国产免费久久久久 | 网站免费黄色 | 久久久久久久久久久福利 | 麻豆国产视频下载 | 韩国av一区二区 | 免费特级黄毛片 | 亚洲日日射 | 999久久久欧美日韩黑人 | av 一区 二区 久久 | 天天插天天狠 | 久久免费视频网 | 国产午夜精品理论片在线 | 在线观看国产中文字幕 | 日本在线观看一区二区 | 国产精品美女999 | 免费色网 | 久久99热这里只有精品 | 麻豆免费在线播放 | 国产亚洲精品xxoo | 国产精品伦一区二区三区视频 | www.色com| 国产精品不卡av | 日韩欧美综合视频 | 夜夜干夜夜 | 在线观看黄av | 美女福利视频 | 国产精品久久久久aaaa | 国产成人亚洲在线观看 | 久久久久久久久久久电影 | 国产成人在线免费观看 | 在线亚洲人成电影网站色www | h网站免费在线观看 | 国产精品久久久久久久久婷婷 | 国产伦理久久 | 亚洲一区二区精品 | 国产精品精品国产 | 亚洲国产精品一区二区久久,亚洲午夜 | 国产精品h在线观看 | 亚洲精品在线二区 | a资源在线 | 国产精品一区二区久久精品爱涩 | 久久精品一区二区三区国产主播 | 在线观看国产麻豆 | 日本三级全黄少妇三2023 | 久久亚洲综合国产精品99麻豆的功能介绍 | 欧美中文字幕第一页 | 麻豆一区在线观看 | 久久99精品久久久久久 | 中文字幕在线乱 | 久久黄色影院 | 国产高清在线观看 | 久国产在线播放 | 成人蜜桃视频 | 色久网 | 91一区啪爱嗯打偷拍欧美 | 91精品啪在线观看国产线免费 | 免费的黄色的网站 | 精品国产一区二区三区av性色 | 免费观看不卡av | 亚洲国产成人在线播放 | 色亚洲网| 99久久精品国产亚洲 | 国产视频在线观看一区二区 | 国产精品久久久久久久久久久免费 | 欧美成年网站 | 欧美日韩中字 | 中文字幕在线网址 | 色婷婷97 | 国产中文字幕网 | www最近高清中文国语在线观看 | 日日精品 | 国产精品久久久久毛片大屁完整版 | 久久国产午夜精品理论片最新版本 | 色偷偷人人澡久久超碰69 | 亚洲高清视频在线观看免费 | 视频在线国产 | 5月丁香婷婷综合 | 在线一二三区 | 日韩在线一二三区 | 少妇啪啪av入口 | 五月天久久激情 | 欧美日韩xxx | 亚洲精品动漫久久久久 | 日韩精品一区二区在线 | 99九九视频 | 美女av免费| 九色porny真实丨国产18 | 在线观看aaa | 一区二区三区播放 | 久久免费精品视频 | 国产不卡视频在线 | 精品综合久久 | 婷婷www | 日本不卡视频 | 欧美国产日韩一区二区三区 | 久草免费在线 | 欧美怡红院 | 色婷婷国产精品一区在线观看 | av免费观看在线 | 亚洲精品视频在线播放 | 久久综合九色综合97婷婷女人 | 中文字幕乱视频 | 中文字幕免费播放 | 国产色视频 | 久久久久久蜜桃一区二区 | 精品国产99 | av一区二区在线观看中文字幕 | 国产高清视频色在线www | 欧美精品一区二区在线播放 | 久久久久网址 | aaaaaa毛片| 在线观看资源 | 黄色小说视频在线 | 亚洲美女免费精品视频在线观看 | 国产精品18久久久久白浆 | 一二三久久久 | 日本字幕网| 五月婷久 | 最新日韩电影 | 国产精品一区二区 91 | 国产一区二区在线观看免费 | 免费av网址大全 | 九九爱免费视频 | 国产精品久久久久久久久久免费看 | 狠狠操狠狠插 | 免费黄av| 亚洲电影免费 | 日本久热 | 97免费在线视频 | 婷婷视频 | 欧美国产亚洲精品久久久8v | 久久久久国产精品厨房 | 亚洲综合小说电影qvod | 在线精品一区二区 | 精品国产人成亚洲区 | 日韩国产精品一区 | 国产91精品看黄网站在线观看动漫 | 欧美成人黄色 | 99热这里只有精品在线观看 | 日韩av一区二区在线播放 | 欧美先锋影音 | 国产精品理论片 | 蜜臀久久99精品久久久久久网站 | 欧美一区二区精品在线 | 国产无区一区二区三麻豆 | 91社区国产高清 | 日韩1级片 | 天堂在线一区二区三区 | 波多野结依在线观看 | 96视频在线 | 99精品久久久久久久 | 国产精品一区二区三区电影 | 三级av黄色| 欧美日韩国产一区二区三区在线观看 | 日韩欧美在线视频一区二区三区 | 免费黄在线看 | 久久伊人操 | 成人中文字幕在线观看 | 五月天综合色激情 | 久久久久久综合 | 亚洲精品国产精品国自产在线 | 麻豆传媒视频在线播放 | 亚洲精品无 | 黄色在线观看免费 | 久久久www成人免费精品张筱雨 | 国产精品亚洲a | 视频二区在线视频 | 亚洲最大av在线播放 | 国产a国产a国产a | 天天干 天天摸 天天操 | 欧美日韩网站 | 91中文在线视频 | 天天夜操 | 免费毛片aaaaaa| 久久久国产99久久国产一 | 日本99精品| 九色视频网 | 在线久久| 国产一级片视频 | 黄色一级大片在线免费看国产一 | 亚州精品天堂中文字幕 | 国产 日韩 中文字幕 | 国产午夜精品福利视频 | 亚洲丝袜一区二区 | 又黄又刺激视频 | 国产一区观看 | 成人在线视频一区 | 亚洲精品国产第一综合99久久 | 欧美大片aaa | av一级片在线观看 | 亚洲欧美精品一区二区 | 久久公开视频 | 婷婷色吧| 国精产品999国精产品视频 | 91精品国产九九九久久久亚洲 | 超碰97免费在线 | 国产精品久久久区三区天天噜 | 久久9视频 | 国产一级91 | 国内精品久久久久影院优 | 亚洲欧美日韩国产一区二区三区 | 91日韩在线专区 | a成人v | 玖操| 亚洲欧美日韩国产一区二区 | 日韩av一区二区在线播放 | 天天爱综合 | 久久久久久国产一区二区三区 | 欧美在线18| 一区二区电影在线观看 | 国产香蕉视频 | 色婷婷成人网 | 亚洲狠狠操 | 国产一二三精品 | 免费看毛片在线 | 亚洲专区在线 | 欧美成人tv | 在线视频观看亚洲 | 丁香五月缴情综合网 | 久久99在线视频 | 日日干美女 | 欧美日韩一区二区在线观看 | 午夜婷婷网 | 久久天天躁夜夜躁狠狠躁2022 | 欧美影院久久 | www.av在线播放 | 99 色| 一区二区不卡 | 中文字幕 国产精品 | 91九色在线观看视频 | 日日干天天 | 欧美a免费 | 精品久久久久久久久久久久久久久久久久 | 日韩午夜大片 | 国产在线资源 | 色久av | 伊人色综合久久天天 | 婷婷伊人网 | 精品久久影院 | 国产96在线 | 国色天香在线观看 | 欧美日韩国产一二 | 免费看一级特黄a大片 | 日日干日日操 | 精品久久一区二区三区 | 日韩一区二区三区免费视频 | 99热最新网址 | 黄色大全免费观看 | 91av在线播放 | 国产精品免费一区二区三区 | 91av电影网 | 一级片视频在线 | 免费看一级一片 | 五月婷婷激情六月 | 国产成人精品日本亚洲999 | 国产高清在线a视频大全 | 亚洲精品一区二区三区四区高清 | 99在线高清视频在线播放 | 久久久久久久久久久久av | 欧美久久久久久久久久久 | 五月婷婷视频在线 | bbw av| 国产黄色片一级三级 | 国产一区二区高清 | 2018亚洲男人天堂 | 国产精品成人av在线 | 制服丝袜欧美 | 婷婷五月色综合 | 日一日干一干 | 一区中文字幕在线观看 | 国产色综合 | 久久久久久影视 | 免费一级黄色 | 99热在线观看免费 | 国产亚洲精品久久久久久 | 丁香花在线观看视频在线 | 色婷婷成人 | 人人干人人草 | 在线观看国产成人av片 | 99热精品在线 | 中文字幕不卡在线88 | 国产精品毛片完整版 | 精品麻豆入口免费 | 91传媒在线观看 | 黄色片免费电影 | 国产手机在线观看视频 | 超碰99在线 | 日本韩国欧美在线观看 | 午夜久久成人 | 国产黄色高清 | 日日夜夜干 | 麻豆果冻剧传媒在线播放 | 五月色婷 | av亚洲产国偷v产偷v自拍小说 | 久久精品久久精品久久 | 黄色影院在线播放 | 日韩欧美视频二区 | 国产精品美女久久久久久2018 | 97超碰影视 | 日韩首页 | 好看av在线 | 亚洲,国产成人av | 国产精品免费观看网站 | 久久久久五月 | 激情av资源 | 亚洲综合色播 | 欧美视频网址 | 国产高清在线不卡 | 超黄视频网站 | 欧美日韩高清一区二区 国产亚洲免费看 | 九九热在线精品 | av+在线播放在线播放 | 国产不卡在线播放 | 天天操天天拍 | 91亚洲精品久久久蜜桃网站 | 欧美一进一出抽搐大尺度视频 | 一本一道波多野毛片中文在线 | 91欧美视频网站 | 亚洲精品国产精品乱码不99热 | 国产免费观看av | 久久免费av电影 | 亚洲精品激情 | 免费日韩 精品中文字幕视频在线 | 国产精品毛片完整版 | av字幕在线 | 精品国产亚洲一区二区麻豆 | 欧美综合在线视频 | 国产精品久久久久9999 | 美女精品网站 | 亚洲激情在线观看 | 性色av一区二区三区在线观看 | 欧美极度另类 | 亚洲午夜久久久久久久久电影网 | 涩av在线 | 日本中文一级片 | 久久理论影院 | 免费av大全| 日韩在线观看第一页 | 狠狠干夜夜操天天爽 | 狠狠狠狠狠狠 | 黄色福利网 | 天天操天天摸天天干 | 国产精品理论视频 | 韩国三级av在线 | 97视频资源 | 在线观看国产 | 精品一区免费 | 狠狠干网址 | 精品国产福利在线 | 色婷在线 | 亚洲三级在线播放 | 在线观看国产永久免费视频 | 久草亚洲视频 | 国产一级片直播 | 一二三区高清 | 国产精品2018 | 久久 一区 | 国产成人精品一区二区三区 | 久久久影院一区二区三区 | 伊人婷婷久久 | 国产精品综合久久久 | 国产一区视频在线 | 亚洲乱亚洲乱妇 | 久久久久久久久毛片 | 中文字幕资源站 | 亚洲精品国产精品99久久 | 久草在线手机观看 | 久草视频在线新免费 | 日日干天夜夜 | 91中文字幕一区 | 狠狠天天 | 久久精品国产亚洲 | 国产69精品久久久久99 | 国产黑丝袜在线 | 久久资源在线 | 日韩在线小视频 | 欧美久久综合 | 国产黄色特级片 | 不卡av免费在线观看 | 久草剧场 | 色午夜影院 | 337p日本欧洲亚洲大胆裸体艺术 | 精品久久久久久亚洲综合网站 | 97高清视频 | 中文字幕国产 | 午夜精品视频在线 | 911国产在线观看 | 久久精品国产精品亚洲 | 国产美女精品视频 | 麻豆av电影 | 日韩美在线观看 | 久久九九久久精品 | 国产成人精品一区二区三区福利 | 狠狠操在线 | 精品99免费| 蜜臀av性久久久久蜜臀av | 色综合久久88色综合天天免费 | 日韩国产精品久久 | 国产在线日本 | 天天插日日插 | 免费久久久久久 | 国产一区二区综合 | 国产日韩在线看 | 综合网伊人 | 日日操日日干 | 国内精品视频一区二区三区八戒 | 亚洲一区二区视频在线播放 | 久久免费视频这里只有精品 | 久久久久久久久久网 | 在线观看视频h | 高清av中文在线字幕观看1 | 亚洲一区二区三区在线看 | 日韩和的一区二在线 | 欧美日韩破处 | av高清免费 | 色视频在线免费 | 最近中文字幕完整视频高清1 | 五月婷婷网站 | 久久精品毛片基地 | 9在线观看免费高清完整 | 国产精品久久久久久久久软件 | 日本精品中文字幕在线观看 | 一级免费片| 欧美日韩国产在线一区 | 日韩av中文| 久久久麻豆| 91系列在线| 国产视频手机在线 | 欧美日韩国产色综合一二三四 | 狂野欧美激情性xxxx | 日韩一区精品 | 人人精品久久 | 久日视频| 粉嫩高清一区二区三区 | 国产精品专区h在线观看 | 国产三级视频 | 久久精品99精品国产香蕉 | 欧美人人 | 久久中文视频 | 日日激情 | 日本精品中文字幕 | 日本一区二区免费在线观看 | 又粗又长又大又爽又黄少妇毛片 | 91在线看网站 | 免费看的av片 | 91精品1区| 国产成人精品在线观看 | 色婷婷久久久综合中文字幕 | 香蕉视频啪啪 | 在线播放精品一区二区三区 | 久久精品之 | 欧美激情综合五月 | 久久66热这里只有精品 | 在线观看国产日韩欧美 | 色黄久久久久久 | 黄色精品久久 | 激情婷婷综合 | 81精品国产乱码久久久久久 | 天堂av免费在线 | 精品91久久久久 | 国产精品理论片 | 99久久99视频 | 99热精品在线 | 久久综合影音 | 91一区二区三区久久久久国产乱 | 黄色午夜网站 | 日韩在线在线 | 日韩在线免费观看视频 | 91看片一区二区三区 | 精品视频国产 | 成人在线一区二区 | 狠狠干在线播放 | 国内精品视频久久 | 日韩av网址在线 | 在线中文字母电影观看 | 国产精品久久在线观看 | 三级黄色a | 亚洲午夜小视频 | 欧美一区二区三区在线观看 | 国产精品一区二区免费 | 男女全黄一级一级高潮免费看 | 国产黄免费| 国产在线a不卡 | 狠狠色丁香婷婷综合 | 在线 日韩 av | 国产精品久久久久免费a∨ 欧美一级性生活片 | 中文字幕国产在线 | 不卡的av| 亚洲欧美va | 天天做天天爱天天爽综合网 | 久久综合久久综合九色 | 免费看片网页 | 中文字幕在线观看1 | 日韩免费一级a毛片在线播放一级 | 久久亚洲欧美 | 久久综合久久综合久久 | 日本中文字幕电影在线免费观看 | 国产黄色片免费观看 | 97在线资源 | 国产精品成人久久 | 亚洲日韩精品欧美一区二区 | 狠狠色网| 中国一区二区视频 | 亚洲成人免费观看 | 日韩美女久久 | 国产精品理论片在线观看 | 亚洲精品国产电影 | 免费观看全黄做爰大片国产 | 日韩精品在线一区 | 91精品国产欧美一区二区成人 | 一区电影| 日韩理论片在线 | 久久99热精品这里久久精品 | 国产高清无线码2021 | 日日爱网址| 免费视频色 | 天天操天天摸天天射 | 久久久www免费电影网 | 97成人免费 | 97成人免费视频 | 亚洲欧美激情插 | 久久国产精品偷 | 日韩一片| 亚洲精品在线电影 | 色香网| 91看片淫黄大片在线播放 | 久久精品小视频 | 国产一区二区视频在线播放 | 欧美日韩不卡在线视频 | av成人在线观看 | 免费黄色网址网站 | 久久国产精品一国产精品 | 欧日韩在线视频 | 天天射网站 | 人人爽人人片 | 91av电影| va视频在线观看 | 欧美一区二区在线刺激视频 | 成人理论电影 | 激情黄色av | 狠狠色狠狠色终合网 | 亚洲国产日韩精品 | 天天干天天摸天天操 | 中文字幕五区 | 久久久观看 | 国产老太婆免费交性大片 | 91福利视频在线 | 亚洲精品影院在线观看 | 日韩欧美在线高清 | 国产无吗一区二区三区在线欢 | 91精品婷婷国产综合久久蝌蚪 | 亚洲精品黄色在线观看 | 国产精品1024| 91精品国产综合久久婷婷香蕉 | 久久久亚洲成人 | 在线看国产日韩 | 97国产精品一区二区 | av大片免费看 | 狠狠色狠狠色合久久伊人 | 国产精品videossex国产高清 | 国产精品自在线拍国产 | 亚洲色综合| 久久综合久久综合久久 | 亚洲精品欧美视频 | 中文伊人 | 日日碰狠狠躁久久躁综合网 | 992tv在线观看网站 | 国产网站在线免费观看 | 免费观看的黄色 | 在线免费黄色毛片 | 成人av日韩| 麻豆视频免费在线观看 | 欧洲视频一区 | 日精品在线观看 | 丁香五月缴情综合网 | 99热只有精品在线观看 | 黄色三级免费观看 | 欧美性生活小视频 | 在线一二区 | 国产99在线免费 | 天天天天色综合 | 国产精品青草综合久久久久99 | 久久久久观看 | 日韩网站在线免费观看 | 久久久久久视频 | av在线之家电影网站 | 天天草综合 | www天天干 | 亚洲精品女 | 久久亚洲私人国产精品va | 日韩欧美精品在线观看视频 | 日本成人黄色片 | 亚洲一区二区三区四区在线视频 | 国产成人一区二区三区免费看 | 国产精品久久久久久久久久 | 在线观看免费成人av | 免费日韩 精品中文字幕视频在线 | 国产精品一区二区久久 | 在线中文字幕视频 | 国产男女爽爽爽免费视频 | 国内三级在线 | 手机成人av在线 | 国产成人精品av久久 | 日本韩国精品在线 | 国产精品爽爽爽 | 91在线porny国产在线看 | 精品嫩模福利一区二区蜜臀 | 青春草视频在线播放 | 99免费在线 | 亚洲视频aaa | 久久视频这里只有精品 | 日韩在线免费视频 | 中文字幕在线观看资源 | 一级淫片a| 91av免费观看 | 亚洲电影黄色 | av丝袜制服 | 精品在线观看一区二区 | 在线免费观看视频一区 | 一区二区精品在线 | 黄色成人91 | 免费日韩av片 | 狠狠色丁香久久婷婷综 | 国产精品久久精品国产 | 久久国产精品一国产精品 | 久久久久久毛片精品免费不卡 | 日日爱视频| 欧美精品久久久久久久久久 | 射九九 | 亚洲国产精品va在线 | 日韩在线网址 | 日日成人网 | 天天天在线综合网 | 玖玖视频免费在线 | 91.dizhi永久地址最新 | 久久成人18免费网站 | 婷婷网在线 | 九九久久成人 | 美女网站在线免费观看 | 国产精品久久99 | 日韩精品一区二区三区电影 | 亚洲欧美国产精品 | 国产精品欧美久久久久三级 | 国产v欧美 | 美女精品久久久 | 久久国产精品99国产精 | 97国产超碰| 999成人免费视频 | 97国产大学生情侣白嫩酒店 | 日韩电影黄色 | 中文字幕在线看视频 | 99综合视频 | 久久免费大片 | 国产成人中文字幕 | 色婷五月| av7777777| 97在线视频观看 | 中文字幕精品www乱入免费视频 | 亚洲 综合 国产 精品 | 天天天天天天操 | 少妇精品久久久一区二区免费 | 国产精品综合久久久 | 六月婷婷久香在线视频 | 日韩中文字幕a | 中文字幕在线观看一区二区三区 | 久久久久一区二区三区 | 在线91播放| 久草精品在线播放 | 久久久久久美女 | av日韩在线网站 | 久久综合九色综合久99 | 成人性生交大片免费看中文网站 | 99精品视频在线播放观看 | 国产精品久久久久久av | 色com| 色综合天天综合在线视频 | 天天爽天天做 | 99在线视频精品 | 国产一区私人高清影院 | 久久天天躁狠狠躁亚洲综合公司 | 国产精品h在线观看 | 亚洲精品一区中文字幕乱码 | 亚洲国产精品久久久久婷婷884 |