亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++中的默認拷貝函數的使用詳情

2020-02-24 14:32:34
字體:
來源:轉載
供稿:網友

《c++編程思想》上說一個類如果沒有拷貝函數,那么編譯器就會自動創建一個默認的拷貝函數。下面就隨武林技術小編來看一下真實的情況吧,一篇C++中的默認拷貝函數的使用詳情,獻給大家。

首先看一個簡單的類X,這個類沒有顯示定義拷貝構造函數。

c++源碼如下:

?

class X {
private:
??? int i;
??? int j;
};

?

int main() {
??? X x1;//先定義對象x1
??? X x2 = x1;//將x1拷貝給x2
}


下面是其匯編代碼:

?

?

?


_main??? PROC

?

; 7??? : int main() {

??? push??? ebp
??? mov??? ebp, esp
??? sub??? esp, 16??????????????????? ; 為對象x1,x2預留16byte的棧空間

; 8??? :???? X x1;//先定義對象x1
; 9??? :???? X x2 = x1;//將x1拷貝給x2

??? mov??? eax, DWORD PTR _x1$[ebp];將x1的首地址里面的內容給寄存器eax,也就將x1中的成員變量i的值給eax
??? mov??? DWORD PTR _x2$[ebp], eax;將eax里面的值寫入x2的首地址,也就是將eax里面的值寫給x2的成員變量i
??? mov??? ecx, DWORD PTR _x1$[ebp+4];將偏移x1首地址4byte的內存里面的值給寄存器eax,也就是將x1中的成員變量j的值給ecx
??? mov??? DWORD PTR _x2$[ebp+4], ecx;將ecx里面的值寫入偏移x2首地址4byte的內存里面,也就是將ecx里面的值寫給x2的成員變量j

; 10?? : }

??? xor??? eax, eax
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 0
_main??? ENDP


從匯編代碼里面可以看出,根本沒有函數被調用,所有的拷貝賦值都是通過寄存器與內存地址相互通信完成。和編譯器提供默認構造函數一樣,可以把這種情況看成是編譯器提供了一個無用的拷貝構造函數。

?

那么,什么時候編譯器才真正的提供默認拷貝構造函數,并且顯示調用呢?

下面是一種情況,類X里面含有虛成員函數:

c++源碼:

?

class X {
private:
??? int i;
??? int j;
public:
??? virtual ~X() {}//虛析構函數
};

?

int main() {
??? X x1;//先定義對象x1
??? X x2 = x1;//將x1拷貝給x2
}


由于這里只討論拷貝函數,所以只看主函數main和拷貝函數里面的匯編代碼:

?

下面是主函數main里面的匯編代碼:

?

_main??? PROC

?

; 9??? : int main() {

??? push??? ebp
??? mov??? ebp, esp
??? sub??? esp, 24??????????????????? ; 由于引入了虛函數,每個類所占的空間編程12byte 成員變量i,j8byte vptr指針4byte 因此這里為x1 x2預留24byte

; 10?? :???? X x1;//先定義對象x1

??? lea??? ecx, DWORD PTR _x1$[ebp];獲取x1的首地址,放入ecx,為調用構造函數的秘密參數傳入,即this
??? call??? ??0X@@QAE@XZ;調用構造函數

; 11?? :???? X x2 = x1;//將x1拷貝給x2

??? lea??? eax, DWORD PTR _x1$[ebp];獲取x1的首地址,放入寄存器eax
??? push??? eax;將eax壓棧,作為拷貝構造函數的參數
??? lea??? ecx, DWORD PTR _x2$[ebp];獲取x2的首地址,放入寄存器ecx,作為調用拷貝構造函數的秘密參數傳入,即this
??? call??? ??0X@@QAE@ABV0@@Z;調用拷貝構造函數

; 12?? : }

??? lea??? ecx, DWORD PTR _x2$[ebp];獲取x2的首地址,放入ecx寄存器,作為調用析構函數傳入的秘密參數,即this
??? call??? ??1X@@UAE@XZ??????????????? ; 調用析構函數
??? lea??? ecx, DWORD PTR _x1$[ebp];獲取x1的首地址,放入ecx寄存器,作為調用析構函數傳入的秘密參數,即this
??????????????????????????????? ;析構的順序與構建的順序相反
??? call??? ??1X@@UAE@XZ??????????????? ; 調用析構函數
??? xor??? eax, eax
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 0
_main??? ENDP


可以看到,編譯器為類X提供了默認的拷貝構造函數(非無用的默認拷貝構造函數),并且顯示調用。

?

由于一個類繼承自虛基類或者繼承自有虛函數成員的基類,使得它本身也含有虛函數成員,因此也就屬于上一種情形。所以編譯器在這種情況下,也會提供非無用的默認拷貝構造函數,并且能夠顯示調用。

下面是第二種情形,類X繼承自類Y,類Y有顯示定義的拷貝構造函數,而類沒有提供拷貝構造函數:

下面是c++源碼:

?

class Y {
private:
??? int j;
public:
?? Y(const Y& y) {}
?? Y() {};//必須為Y提供默認的構造函數,否則編譯出錯
};
class X : public Y {
private:
??? int i;
??? int j;
};

?


int main() {
??? X x1;//先定義對象x1
??? X x2 = x1;//將x1拷貝給x2
}


下面是mian函數匯編代碼:

?

?

?


; 16?? : int main() {

?

??? push??? ebp
??? mov??? ebp, esp
??? sub??? esp, 24??????????????????? ; 為x1 x2預留24byte空間

; 17?? :???? X x1;//先定義對象x1

??? lea??? ecx, DWORD PTR _x1$[ebp];獲取x1的首地址,作為隱含參數傳遞給構造函數
??? call??? ??0X@@QAE@XZ;//調用編譯器為類X提供的默認構造函數

; 18?? :???? X x2 = x1;//將x1拷貝給x2

??? lea??? eax, DWORD PTR _x1$[ebp];獲取x1的首地址,傳給寄存器eax
??? push??? eax;將eax壓棧,作為調用類X的拷貝構造函數的參數
??? lea??? ecx, DWORD PTR _x2$[ebp];獲取x2的首地址,作為調用類X的拷貝函數的隱含參數
??? call??? ??0X@@QAE@ABV0@@Z;調用編譯器提供的默認拷貝構造函數

; 19?? : }

??? xor??? eax, eax
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 0


下面是類X的拷貝構造函數的匯編碼:

?

?

?


??0X@@QAE@ABV0@@Z PROC??????????????????? ; X::X, COMDAT
; _this$ = ecx
??? push??? ebp
??? mov??? ebp, esp
??? push??? ecx
??? mov??? DWORD PTR _this$[ebp], ecx;ecx里面有x2的首地址
??? mov??? eax, DWORD PTR ___that$[ebp];將x1的首地址給eax
??? push??? eax;將eax的首地址壓棧,作為調用父類拷貝構造函數的參數
??? mov??? ecx, DWORD PTR _this$[ebp];將x2的首地址給ecx,作為隱含參數傳給父類的拷貝構造函數
??? call??? ??0Y@@QAE@ABV0@@Z??????????? ; 調用父類拷貝構造函數
??? mov??? ecx, DWORD PTR _this$[ebp];獲取x2的首地址給ecx
??? mov??? edx, DWORD PTR ___that$[ebp];獲取x1的首地址給edx
??? mov??? eax, DWORD PTR [edx+4];將偏移x1首地址4byte處的內存里面的值寫給eax,即將x1中子類成員變量i的值寫給eax,因為x1的首地址處存放的是父類成員變量i,其值
????????????????????????????? ;由父類拷貝構造函數負責拷貝給x2
??? mov??? DWORD PTR [ecx+4], eax;將eax的值寫入偏離x2首地址4byte處的內存里面,即將eax的值寫入x2中子類成員變量i,因為x2的首地址處存放父類成員變量i,其值
????????????????????????????? ;由父類拷貝構造函數負責拷貝
??? mov??? ecx, DWORD PTR _this$[ebp];將x2的首地址給ecx
??? mov??? edx, DWORD PTR ___that$[ebp];將x1的首地址給edx
??? mov??? eax, DWORD PTR [edx+8];將偏移x1首地址8byte處的內存里面的值給eax,即將x1中子類成員變量j的值給eax
??? mov??? DWORD PTR [ecx+8], eax;將eax的值寫入偏移x2首地址8byte的內存里面,即將eax的值寫入x2子類成員j中
??? mov??? eax, DWORD PTR _this$[ebp];將x2的首地址給eax,作為返回值。構造函數總是返回對象首地址
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 4
??0X@@QAE@ABV0@@Z ENDP


從匯編碼中可以看到,編譯器確實為類X提供了默認的拷貝構造函數,并且進行了顯示調用。而且在調用類X的拷貝構造函數中,首先調用父類的拷貝構造函數,拷貝父類中的成員變量,然后再拷貝子類中的成員變量。

?

下面是父類Y中的拷貝構造函數匯編碼:

?

??0Y@@QAE@ABV0@@Z PROC??????????????????? ; Y::Y, COMDAT
; _this$ = ecx

?

; 5??? :??? Y(const Y& y) {}

??? push??? ebp
??? mov??? ebp, esp
??? push??? ecx;//這里壓棧的目的是為隱含傳給父類拷貝函數的this(即x2的首地址)
??? mov??? DWORD PTR _this$[ebp], ecx;ecx里面含有x2的首地址(即this),放入剛才的預留空間
??? mov??? eax, DWORD PTR _this$[ebp];將x2的首地址寫入eax,作為返回值。構造函數總是返回對象首地址
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 4
??0Y@@QAE@ABV0@@Z ENDP??????????????????? ; Y::Y
_TEXT??? ENDS


從匯編嗎可以看到,由于父類自己顯示定義了拷貝構造函數,編譯器只是負責調用而已,并不提供像上面子類X里面默認拷貝構造函數的拷貝功能,即并不拷貝父類成員變量i。因為,在c++源碼里面,父類拷貝構造函數本身就是空函數,什么也不做。

?

如果子類X 父類Y都不提供拷貝構造函數,情形有時怎樣的呢?

下面是c++源碼:

?

class Y {
private:
??? int j;
};
class X : public Y {
private:
??? int i;
??? int j;
};

?


int main() {
??? X x1;//先定義對象x1
??? X x2 = x1;//將x1拷貝給x2
}


下面是對應的匯編碼:

?

?

?


_main??? PROC

?

; 12?? : int main() {

??? push??? ebp
??? mov??? ebp, esp
??? sub??? esp, 24??????????????????? ; 為x1 x2預留24byte空間

; 13?? :???? X x1;//先定義對象x1
; 14?? :???? X x2 = x1;//將x1拷貝給x2

??? mov??? eax, DWORD PTR _x1$[ebp];獲取x1的首地址里面的值,存入eax,即獲取x1父類成員變量i的值寫給eax
??? mov??? DWORD PTR _x2$[ebp], eax;將eax的值寫入x2的首地址指向的內存,即將eax的值寫給x2中的父類成員變量i
??? mov??? ecx, DWORD PTR _x1$[ebp+4];獲取偏移x1首地址4byte處的內存里面的值,寫入ecx,即獲取x1子類成員變量i的值寫給ecx
??? mov??? DWORD PTR _x2$[ebp+4], ecx;將ecx的值寫入偏移x2首地址4byte處的內存里面,即將ecx的值寫給x2中子類成員變量i
??? mov??? edx, DWORD PTR _x1$[ebp+8];獲取偏移x1首地址8byte處的內存里面的值,寫入edx,即獲取x1子類成員變量j的值寫給edx
??? mov??? DWORD PTR _x2$[ebp+8], edx;將edx的值寫入偏移x2首地址8byte處的內存里面,即將edx的值寫入x2子類成員變量j

; 15?? : }

??? xor??? eax, eax
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 0
_main??? ENDP


可以看到,編譯器執行了拷貝過程,但是提供的是像剛開始的無用的默認拷貝構造函數,無論是拷貝父類成員變量,還是子類成員變量,都沒有函數的調用。

?

下面看第三種情況,類X含有類Y的成員變量,類Y的成員變量有拷貝構造函數。

c++源碼如下:

?

class Y {
private:
??? int j;
public:
??? Y(const Y& y) {}
??? Y() {}//必須為Y提供默認的構造函數,否則編譯報錯
};
class X? {
private:
??? int i;
??? int j;
??? Y y;
};

?


int main() {
??? X x1;//先定義對象x1
??? X x2 = x1;//將x1拷貝給x2
}


下面是main函數中的匯編碼:

?

?

?


_main??? PROC

?

; 16?? : int main() {

??? push??? ebp
??? mov??? ebp, esp
??? sub??? esp, 24??????????????????? ; 為x1 x2預留24byte的空間

; 17?? :???? X x1;//先定義對象x1

??? lea??? ecx, DWORD PTR _x1$[ebp];獲取x1的首地址,作為隱含參數傳遞給構造函數
??? call??? ??0X@@QAE@XZ;調用構造函數

; 18?? :???? X x2 = x1;//將x1拷貝給x2

??? lea??? eax, DWORD PTR _x1$[ebp];獲取x1的首地址,放入寄存器eax
??? push??? eax;將eax壓棧,為作為參數傳遞給編譯器提供的默認拷貝構造函數
??? lea??? ecx, DWORD PTR _x2$[ebp];獲取x2的首地址,作為隱含參數傳遞給編譯器提供的默認拷貝構造函數
??? call??? ??0X@@QAE@ABV0@@Z;調用拷貝構造函數

; 19?? : }

??? xor??? eax, eax
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 0
_main??? ENDP


下面是編譯器為類X提供的默認拷貝構造函數的匯編碼:

?

?

?


??0X@@QAE@ABV0@@Z PROC??????????????????? ; X::X, COMDAT
; _this$ = ecx
??? push??? ebp
??? mov??? ebp, esp
??? push??? ecx;壓棧的目的是為this(即x2的首地址)預留空間
??? mov??? DWORD PTR _this$[ebp], ecx;ecx里面含有x2的首地址,放入剛才預留的空間里面
??? mov??? eax, DWORD PTR _this$[ebp];將x2的首地址給eax
??? mov??? ecx, DWORD PTR ___that$[ebp];將x1的首地址給ecx
??? mov??? edx, DWORD PTR [ecx];將x1的首地址的內容寫入edx,即將x1中的成員變量i寫入edx
??? mov??? DWORD PTR [eax], edx;將edx的值寫入x2的首地址,即將edx的值寫入x2的成員變量i
??? mov??? eax, DWORD PTR _this$[ebp];將x2的首地址寫入寄存器eax
??? mov??? ecx, DWORD PTR ___that$[ebp];將x1的首地址寫入寄存器ecx
??? mov??? edx, DWORD PTR [ecx+4];將偏移x1首地址4byte處的內存里面的值寫入edx,即將x1的成員變量j的值寫入edx
??? mov??? DWORD PTR [eax+4], edx;將edx的值寫入偏移x2首地址4byte處的內存,即將edx的值寫入x2的成員變量j
??? mov??? eax, DWORD PTR ___that$[ebp];將x1的首地址存入寄存器eax
??? add??? eax, 8;//將x1的首地址加8,得到x1中成員對象y所處的地址,放入eax中
??? push??? eax;將eax的值壓棧,作為調用成員變量y的拷貝函數的參數
??? mov??? ecx, DWORD PTR _this$[ebp];將x2的首地址存入寄存器ecx
??? add??? ecx, 8;將x2的首地址加8,得到x2中成員對象y所在地址,放入ecx,這個地址作為隱含的參數傳給成員變量函數的拷貝構造函數
??? call??? ??0Y@@QAE@ABV0@@Z??????????? ; 調用成員對象y的拷貝構造函數
??? mov??? eax, DWORD PTR _this$[ebp];將x2的首地址放入eax,作為返回值。構造函數總是返回對象的首地址
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 4
??0X@@QAE@ABV0@@Z ENDP


從匯編嗎可以看到,調用類X拷貝構造函數的時候,先將x1中的成員變量i,j拷貝到x2中,然后才是調用成員對象y的拷貝構造函數拷貝y中的成員變量。這和繼承不同,在繼承中,總是先調用父類的拷貝構造函數,再進行子類中的拷貝。這說明,對于這種包含成員對象的情況,成員對象的拷貝函數調用時機與他們定義的位置有關。在這里,類X的成員對象y在成員變量i,j之后定義,因此,它的拷貝構造函數要等拷貝完i,j之后才會被調用。

?

下面是類Y中的拷貝構造函數匯編代碼:

?

??0Y@@QAE@ABV0@@Z PROC??????????????????? ; Y::Y, COMDAT
; _this$ = ecx

?

; 6??? :???? Y(const Y& y) {}

??? push??? ebp
??? mov??? ebp, esp
??? push??? ecx;壓棧ecx的目的是為了存放this(x2中成員對象y的首地址)預留空間
??? mov??? DWORD PTR _this$[ebp], ecx;ecx里面有x2中成員對象y的首地址,放入剛才的預留空間
??? mov??? eax, DWORD PTR _this$[ebp];將x2中成員變量首地址放入eax,作為返回值。構造函數總是返回對象首地址
??? mov??? esp, ebp
??? pop??? ebp
??? ret??? 4
??0Y@@QAE@ABV0@@Z ENDP


從代碼中可以看到,由于類Y顯示定義了拷貝構造函數,編譯器也只是負責顯示調用,并沒有提供任何的拷貝功能。因為在類Y中,拷貝構造函數就是被定義成了一個空函數

?

和繼承一樣,如果成員對象也沒有拷貝構造函數呢?

下面是c++源碼:

?

class Y {
private:
??? int j;

?

};
class X? {
private:
??? int i;
??? int j;
??? Y y;
};


int main() {
??? X x1;//先定義對象x1
??? X x2 = x1;//將x1拷貝給x2
}


下面是對象的匯編碼:

?

?

?


_main??? PROC

?

; 14?? : int main() {

??? push??? ebp
??? mov??? ebp, esp
??? sub??? esp, 24??????????????????? ; 00000018H

; 15?? :???? X x1;//先定義對象x1
; 16?? :???? X x2 = x1;//將x1拷貝給x2

??? mov??? eax, DWORD PTR _x1$[ebp];將x1中首地址的內容寫入eax,即將x1中的成員變量值i寫入eax
??? mov??? DWORD PTR _x2$[ebp], eax;將eax的值寫入x2的首地址處,即將eax的值寫入x2的成員變量i
??? mov??? ecx, DWORD PTR _x1$[ebp+4];將偏移x1首地址4byte處的內存里面的內容寫入ecx,即將x1中成員變量j的值寫入ecx
??? mov??? DWORD PTR _x2$[ebp+4], ecx;將ecx的值寫入偏移x2首地址4byte處的內存,即將ecx的值寫入x2中成員變量j
??? mov??? edx, DWORD PTR _x1$[ebp+8];將偏移x1首地址8byte處(這里是x1成員對象y的首地址)的內存值寫入edx,即將x1中成員對象y中的成員變量i值寫入edx
??? mov??? DWORD PTR _x2$[ebp+8], edx;將edx的值寫入偏移x2首地址8byte處(這里是x2成員對象y的首地址)的內存里面,即將edx的值寫入x2中成員對象y的成員變量i里面


從匯編嗎可以看出,編譯器在這種情況下任然只是提供無用的默認拷貝構造函數,即沒有顯示的函數調用,只是用寄存器和內存之間的通信完成拷貝過程

?

綜合上面的分析,可以看到:

對于一個類,如果它沒有顯示定義拷貝構造函數,編譯器并不總是提供非無用的默認拷貝構造函數,除非:

1 該類包含虛函數成員函數(包括繼承自虛基類或者繼承的基類中有虛函數成員),這時編譯器提供為該類提供非無用的默認拷貝構造函數

2 該類繼承自一個基類,而基類含有自定義的拷貝函數,這時編譯器為該類提供非無用的默認拷貝構造函數。(如果基類本身沒有定義拷貝構造函數,但是編譯器會為基類提供一個非無用的默認拷貝構造函數,也屬于這種情況。也就是說,基類只要含有一個非無用的拷貝構造函數就行,不管這個非無用的拷貝構造函數是自定義的,還是編譯器提供的)

3 該類包含一個成員對象,而該成員對象有自定的拷貝構造函數,這時編譯器為該類提供非無用的默認拷貝構造函數。(如果成員對象本身沒有定義拷貝構造函數,但是編譯器會為成員對象提供一個非無用的默認拷貝構造函數,也屬于這種情況。也就是說,成員對象只要包含一個非無用的拷貝構造函數就行,不管這個非無用的拷貝構造函數時自定義的,還是編譯器提供的。這中情況和上一種類似).

并且,如果一個類自定義了一個拷貝構造函數,編譯器只是負責調用,不會額外提供任何拷貝過程;而對于編譯器提供的默認拷貝函數,不管是無用的,還是非無用的,都僅僅只是位拷貝(即淺拷貝).

以上就是武林技術頻道的編輯獻給大家的C++中的默認拷貝函數的使用詳情,希望你正好需要,更多精彩內容,請繼續關注武林技術頻道。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久亚洲电影天堂| 亚洲一区二区少妇| 国产91对白在线播放| 久久综合88中文色鬼| 国产日韩欧美中文在线播放| 亚洲欧美色婷婷| 91av福利视频| 日本成人免费在线| 亚洲系列中文字幕| 俺去亚洲欧洲欧美日韩| 国产成人精品免费久久久久| 91欧美日韩一区| 亚洲精品午夜精品| 国产午夜精品久久久| 国产精品美女网站| 日韩精品视频三区| 欧美www视频在线观看| 一本一本久久a久久精品牛牛影视| 国内揄拍国内精品| 中文字幕亚洲欧美日韩高清| 久久影视三级福利片| 日韩欧美在线网址| 亚洲小视频在线| 青青草国产精品一区二区| 日本亚洲欧洲色| 久久婷婷国产麻豆91天堂| 欧美专区国产专区| 国产日本欧美一区二区三区| 精品视频9999| 国产精品女主播| 高清视频欧美一级| 亚洲激情视频在线观看| 91av在线不卡| 91九色综合久久| 国产精品久久久久久网站| 一个人www欧美| 日韩在线视频一区| 在线成人激情视频| 精品久久久一区| 久久亚洲春色中文字幕| 久久精品免费播放| 久久精品人人做人人爽| 亚洲精品美女在线观看播放| 欧美激情中文字幕乱码免费| 久久久女人电视剧免费播放下载| 456亚洲影院| 在线观看日韩视频| 一本色道久久综合狠狠躁篇的优点| 韩国v欧美v日本v亚洲| 久久久亚洲天堂| 97国产精品视频| 色综合视频网站| 欧美电影免费观看大全| 亚洲天堂男人天堂女人天堂| 亚洲丝袜av一区| 日本精品视频在线| 精品欧美国产一区二区三区| 清纯唯美日韩制服另类| 亚洲国产精品久久| 成人福利网站在线观看11| 欧美国产日韩二区| 亚洲在线第一页| 亚洲精品国产拍免费91在线| 欧洲精品毛片网站| 91亚洲国产成人久久精品网站| 国产精品美女久久久免费| 国产成人+综合亚洲+天堂| 久久免费视频这里只有精品| 日韩av免费在线播放| 久久亚洲国产成人| 日韩欧美亚洲国产一区| 欧美国产日本在线| 久久综合久久八八| 国产999在线| 一区二区三区国产在线观看| 亚洲精品美女在线观看播放| 国产美女被下药99| 性欧美长视频免费观看不卡| 久久久久99精品久久久久| 久久久97精品| 亚洲人成在线观| 97视频网站入口| 欧美日韩裸体免费视频| 亚洲午夜精品久久久久久性色| 欧美精品18videos性欧美| 欧美高清视频免费观看| 超碰97人人做人人爱少妇| 欧美亚洲另类在线| 91精品国产色综合久久不卡98| 国产欧美一区二区三区久久| 欧美最猛性xxxxx免费| 91精品国产高清自在线看超| 亚洲另类图片色| 日韩在线小视频| 日韩av黄色在线观看| 国产欧洲精品视频| 91亚洲永久免费精品| 亚洲日本欧美日韩高观看| 精品magnet| 91久久久久久久| 成人在线精品视频| 欧美一级淫片丝袜脚交| 日韩av一区二区在线观看| 91亚洲va在线va天堂va国| 久久视频免费观看| 亚洲视频在线观看视频| 欧美猛少妇色xxxxx| 国产精品福利网站| 亚洲成人性视频| 精品福利一区二区| 国产丝袜视频一区| 亚洲欧美日韩直播| 青青a在线精品免费观看| 国产色婷婷国产综合在线理论片a| 激情亚洲一区二区三区四区| 国产欧美日韩免费看aⅴ视频| 日韩精品免费在线观看| 久久精品国产清自在天天线| 91av在线免费观看视频| 九九视频这里只有精品| 亚洲激情自拍图| 国产区精品在线观看| 欧美激情影音先锋| 国产91精品在线播放| 操日韩av在线电影| 欧美午夜视频一区二区| 97国产真实伦对白精彩视频8| 午夜精品视频网站| 欧美性猛交xxxx久久久| 狠狠干狠狠久久| 亚洲天堂开心观看| 欧美限制级电影在线观看| 亚洲精品99久久久久| 国产日韩在线亚洲字幕中文| 久久免费少妇高潮久久精品99| 亚洲成人av资源网| 91精品视频在线免费观看| 91亚洲精华国产精华| 欧美亚洲国产精品| 97久久久免费福利网址| 黑人巨大精品欧美一区免费视频| 91在线免费视频| 中文字幕日韩精品在线观看| 高清欧美电影在线| 国产女精品视频网站免费| 亚洲欧美日韩一区二区在线| 在线午夜精品自拍| 中文欧美在线视频| 国产成人一区二| 亚洲欧美日韩久久久久久| 久久久久久综合网天天| 国产成人精品久久亚洲高清不卡| 疯狂欧美牲乱大交777| 亚洲最大福利网站| 亚洲久久久久久久久久久| 亚洲区一区二区| 在线日韩日本国产亚洲| 欧美午夜视频在线观看| 菠萝蜜影院一区二区免费| 亚洲精品视频免费在线观看| 精品福利在线观看| 国产精品美女999| 8090成年在线看片午夜| 国产欧美在线视频|