色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C++ const、volatile和mutable關(guān)鍵字詳解

冬至子 ? 來(lái)源:iDoitnow ? 作者:艱默 ? 2023-07-18 16:49 ? 次閱讀

對(duì)于cvconstvolatile)類型限定符和關(guān)鍵字mutable在《cppreference》中的定義為:

cv可出現(xiàn)于任何類型說(shuō)明符中,以指定被聲明對(duì)象或被命名類型的常量性(constness)或易變性(volatility)。

  • const ----------定義類型為常量類型。
  • volatile --------定義類型為易變類型。

mutable用于指定不影響類的外部可觀察狀態(tài)的成員(通常用于互斥體、記憶緩存、惰性求值和訪問(wèn)指令等)。

  • mutable ------容許常量類類型對(duì)象修改相應(yīng)類成員。

const

const實(shí)際上是一個(gè)類型說(shuō)明,告訴編譯器const修飾的目標(biāo)是不變的,允許編譯器對(duì)其進(jìn)行額外的優(yōu)化,如果后面代碼不小心修改它了,就編譯失敗,告訴用戶該目標(biāo)被意外修改了,提高程序的安全性和可控性。

const修飾普通變量

const修飾過(guò)的變量,編譯器往往將其作為一個(gè)常量進(jìn)行處理,同時(shí),const修飾的變量在編譯階段會(huì)被編譯器替換為相應(yīng)的值,來(lái)提高程序的執(zhí)行效率。

#include < iostream >

using namespace std;

int main() {
  const int i = 50;          // 普通常量
  const static int si = 50;  // 靜態(tài)常量

  int* p_int = (int*)&i;  // 強(qiáng)制類型轉(zhuǎn)換為int*
  int* p_sint = (int*)&si;
  *p_int = 100;  // 通過(guò)非常常量指針修改常量i的值,該行為是C++為未定義行為
  //*p_sint = 100;//編譯不會(huì)報(bào)錯(cuò),程序運(yùn)行時(shí)崩潰,且該行為也是C++為未定義行為

  cout < < "i:" < < i < < ", i的地址: " < < &i < < endl;//編譯器階段會(huì)將常量i替換為50
  cout < < "*p_int:" < < *p_int < < ", *p_int的地址: " < < p_int < < endl;

  return 0;
}

:類型是 const修飾的對(duì)象,或常量對(duì)象的非可變子對(duì)象。這種對(duì)象不能被修改: 直接嘗試這么做是編譯時(shí)錯(cuò)誤,而間接嘗試這么做(例如通過(guò)到非常量類型的引用或指針修改常量對(duì)象)的行為未定義。

輸出結(jié)果:

i:50, i的地址: 0x7fffffffd9d4
*p_int:100, *p_int的地址: 0x7fffffffd9d4

i*p_int打印出的地址都是0x7fffffffd9d4可以看出,我們偷偷修改i的值成功了(但該行為是C++未定義的行為),但是為何i*p_int的結(jié)果卻是不同的,這就從側(cè)面證實(shí)了const常量具有宏替換的特性,即程序在編譯階段就會(huì)其進(jìn)行部分的替換,例如上述例子中對(duì)語(yǔ)句

cout < < "i:" < < i < < ", i的地址: " < < &i < < endl;

在編譯階段替換為

cout < < "i:" < < 50 < < ", i的地址: " < < &i < < endl;

因此導(dǎo)致我們輸出的i的值為50

同時(shí),當(dāng)我們想要通過(guò)使用非常量指針修改靜態(tài)常量si時(shí)候,編譯通過(guò),但是在運(yùn)行過(guò)程中導(dǎo)致程序崩潰(這就是不按規(guī)矩辦事的后果,使用了C++未定義的行為,編譯器也幫不了我們,最終導(dǎo)致程序掛掉)。

const的內(nèi)部鏈接性

通常情況下,在未聲明為 extern 的變量聲明上使用 const 限定符,會(huì)給予該變量?jī)?nèi)部連接(即名稱在用于聲明變量的文件的外部是不可見(jiàn)的)的特性。即與static類似,但是與其不同的是其可以通過(guò)extern來(lái)改變其內(nèi)部連接性。

const修飾指針和引用

/********指針********/
//指向const對(duì)象的指針
const int* p1; //const修飾的是int,表示p1指向的內(nèi)容不能被修改
int const* p2; //const修飾的是int,表示p2指向的內(nèi)容不能被修改

//指向?qū)ο蟮腸onst指針
int* const p3; //const修飾的是*,表示p3的指向不能被修改

//指向const對(duì)象的const指針
const int* const p4; //第一個(gè)修飾的是int,第二個(gè)修飾的是*,表示p4指向的內(nèi)容和p4的指向都不能被修改
const int const* p5; //同上,表示p5指向的內(nèi)容和p5的指向都不能被修改


/*注:從上面我們可以總結(jié)出來(lái)的一個(gè)規(guī)律:
const優(yōu)先修飾其左邊最近的類型,
如果左邊沒(méi)有,就修飾右邊離他最近的那個(gè)*/


/********引用********/
const int a = 0;
//由于a1引用a之后,不能引用其他實(shí)體,所以對(duì)于const int&可以看作是const int* const
const int& a1 = a; 

int b = 0;
const int& b1 = b;//C++允許無(wú)限定類型的引用/指針能被轉(zhuǎn)換成到 const 的引用/指針

const在類中的應(yīng)用

非靜態(tài)數(shù)據(jù)成員可以被cv限定符修飾,這些限定符寫在函數(shù)聲明中的形參列表之后。其中,帶有不同cv限定符(或者沒(méi)有)的函數(shù)具有不同的類型,它們可以相互重載。在具有cv限定符的成員函數(shù)內(nèi),*this擁有同向的cv限定。例子如下:

#include < iostream >

using namespace std;

class A {
    public:
    A(int a) : a(a){};

    void show() { cout < < "void show(): " < < a < < endl; }
    void show() const { cout < < "void show() const: " < < a < < endl; }  // 重載
    /*這里
  void show() 等價(jià)于 void show(A* this)
  void show() const 等價(jià)于 void show(const A* this)
  因此該成員函數(shù)show()可以被重載
  */

    void set_a(int n) { a = n; }
    /*
  void set_a(int n) const
  {
      a = n;//此時(shí)*this擁有const限制,導(dǎo)致a不能夠被修改
  }//程序報(bào)錯(cuò)
  */

    // void print_a() const 等價(jià)于 void print_a(const A* this)
    void print_a() const { cout < < "print_a() const: " < < a < < endl; }

    private:
    int a;
};

int main() {
    A a1(1);
    const A a2(2);

    a1.show();
    a2.show();


    a1.print_a();  // 非const對(duì)象可以調(diào)用const成員函數(shù)
    // 根本原因是A* this可以隱式轉(zhuǎn)換const A* this
    // 最終調(diào)用void print_a(const A* this)
    // 即void print_a() const
    a2.print_a();


    a1.set_a(2);
    //   a2.set_a(1);  // 編譯報(bào)錯(cuò),const對(duì)象不能調(diào)用非const成員函數(shù),根本原因是根本原因是const A* this可以隱式轉(zhuǎn)換A* this

    return 0;
}

輸出結(jié)果:

void show(): 1
void show() const: 2
print_a() const: 1
print_a() const: 2

對(duì)于上述例子我們可以得出:

  • const對(duì)象不能調(diào)用非const成員函數(shù)。 => const成員函數(shù)內(nèi)部不能調(diào)用其他非cosnt成員函數(shù)。
  • const對(duì)象可以調(diào)用const成員函數(shù)。=> 非cosnt成員函數(shù)可以調(diào)用其他cosnt成員函數(shù)。

volatile

volatile 主要作用是告訴編譯器其修飾的目標(biāo)是易變的,在編譯的時(shí)候不要去優(yōu)化它(例如讀取的時(shí)候,都從目標(biāo)內(nèi)存地址讀取),防止編譯器誤認(rèn)為某段代碼中目標(biāo)是不會(huì)被改變,而造成過(guò)度優(yōu)化。

:編譯器大部分情況是從內(nèi)存讀取變量的值的,但有時(shí)候編譯器認(rèn)為在某段代碼中,某個(gè)變量的值是沒(méi)有變化的,所以認(rèn)為寄存器里的值跟內(nèi)存里是一樣的,為了提高讀取速度,編譯器可能會(huì)從寄存器中讀取變量,但是在某些情況下變量的值被其他元素(如另外一個(gè)線程或者中斷服務(wù))修改,這樣導(dǎo)致程序讀取變量的值不是最新的,產(chǎn)生異常。

因此,volatile 關(guān)鍵字對(duì)于聲明共享內(nèi)存中可由多個(gè)進(jìn)程訪問(wèn)的對(duì)象或用于與中斷服務(wù)例程通信的全局?jǐn)?shù)據(jù)區(qū)域很有用。如果某個(gè)目標(biāo)被聲明為 volatile,則每當(dāng)程序訪問(wèn)它的時(shí)候,編譯器都會(huì)重新加載內(nèi)存中的值。 這雖然降低了目標(biāo)的讀取速度,但是保證了目標(biāo)讀取的正確性,這也是保證我們程序可預(yù)見(jiàn)性的唯一方法。

下面我們通過(guò)一個(gè)讀取系統(tǒng)時(shí)間的例子來(lái)看一下volatile在實(shí)際開(kāi)發(fā)過(guò)程中的應(yīng)用:

#include < iostream >
#include < ctime >
#include < unistd.h >
// #include < windows.h > //win下為該頭文件

using namespace std;
int main()
{
  const time_t time_val = 0; 
  time_t *p_time_t = const_cast< time_t * >(&time_val);

  time(p_time_t);
  cout < < time_val < < endl;

  // 休眠1s
  sleep(1); // linux下sleep函數(shù),單位為秒
  // Sleep(1000); // win下的sleep函數(shù),單位為毫秒

  time(p_time_t);
  cout < < time_val < < endl;

  return 0;
}

time函數(shù)在ctime頭文件中定義,其主要作用是獲取系統(tǒng)當(dāng)前時(shí)間,其原型如下:

std::time_t time( std::time_t* arg );

返回編碼為std::time_t對(duì)象的當(dāng)前日歷時(shí)間,并將它存儲(chǔ)于 arg 所指向的對(duì)象,除非 arg 是空指針。

輸出結(jié)果:

0
0

很明顯結(jié)果不符合我們的預(yù)期,具體原因就是我們上面介紹的 const常量具有宏替換的特性 ,編譯器認(rèn)為這段可以更好的優(yōu)化,在編譯階段就對(duì)其進(jìn)行了替換。那我們?nèi)绾涡薷牟拍苓_(dá)到我們的實(shí)現(xiàn)呢?對(duì),就是添加volatile關(guān)鍵字修飾,具體實(shí)現(xiàn)如下:

#include < iostream >
#include < ctime >
#include < unistd.h >
// #include < windows.h > //win下為該頭文件

using namespace std;
int main()
{
  volatile const time_t time_val = 0;
  time_t *p_time_t = const_cast< time_t * >(&time_val);

  time(p_time_t);
  cout < < time_val < < endl;

  // 休眠1s
  sleep(1); // linux下sleep函數(shù),單位為秒
  // Sleep(1000); // win下的sleep函數(shù),單位為毫秒

  time(p_time_t);
  cout < < time_val < < endl;

  return 0;
}

輸出結(jié)果:

1680339937
1680339938

從輸出結(jié)果看出,結(jié)果符合我們的預(yù)期。

這時(shí)候你可能會(huì)有疑問(wèn):volatile const是什么鬼?const表示time_val是常量,volatile表示time_val是可變的,難道是易變的常量?這不是矛盾嗎?

這里我們確實(shí)可以將time_val成為易變的常量,只不過(guò)常量(不可修改)意味著time_val在其作用域中(這里指的是main函數(shù)中)是不可以被改變的,但是在其作用域外面(這里指的是time()函數(shù)內(nèi))是可以被改變的。volatile const其實(shí)是在告訴編譯器,在main()函數(shù)內(nèi),time_valconst的,你幫我看點(diǎn),我不能隨意的修改,但這個(gè)值在作用域外可能會(huì)被其他東西修改,這玩意也是volatile的,你編譯的時(shí)候也別優(yōu)化它了,在每次讀取的時(shí)候,也老老實(shí)實(shí)從它的存儲(chǔ)位置重新讀取吧。

注:volatile constconst volatile是一樣的,都代表易變的常量。

volatile修飾常量、指針和引用

volatile修飾常量指針和引用的使用方法域const類似,這里不做過(guò)多的解釋,但需要注意的是volatile沒(méi)有像const的內(nèi)部鏈接屬性。

volatile修飾函數(shù)的參數(shù)

int sequare(volatile int* ptr)
{
  return *ptr * *ptr;
}

上述例子是為了計(jì)算一個(gè)易變類型的int的平方,但是函數(shù)內(nèi)部實(shí)現(xiàn)存在問(wèn)題,因?yàn)?/p>

return *ptr * *ptr;

其處理邏輯類似下面的情況:

int a = *ptr; 
int b = *ptr;
return a * b;

由于*ptr是易變的,因此ab獲取的值可能是不一樣的,因此最好采用如下的方式:

int sequare(volatile int* ptr)
{
  int a = *ptr;
  return a * a;
}

mutable

mutable主要是為了突破const的某些限制而設(shè)定的,即允許常量類型對(duì)象相應(yīng)的類成員可以被修改,其常在非引用非常量類型的非靜態(tài)數(shù)據(jù)成員中出現(xiàn)。

在上面的介紹中,我們知道在在獲取類某些狀態(tài)的成員函數(shù)中,如果不涉及狀態(tài)的變更,我們一般會(huì)將成員函數(shù)聲明成const,這將意味著在該函數(shù)中,所有的成員函數(shù)都不可以被修改,但有些時(shí)候我們需要在該const函數(shù)中修改一些跟類狀態(tài)無(wú)關(guān)的數(shù)據(jù)乘員,那么這時(shí)候就需要mutable發(fā)揮作用了,即將該需要修改的成員使用mutable修飾。

#include < iostream >
using namespace std;

class A
{
public:
  A(int data = 0) : int_data(data), times(0) {}
  void show() const
  {
    times++; //因?yàn)閠imes被mutable修飾,突破了const的限制
    cout < < "data : " < < int_data < < endl;
  }

  int getNumOfCalls() { return times; }

private:
  int int_data;
  mutable int times;
};

int main()
{
  A a(1);
  cout < < "a的show()被調(diào)用了:" < < a.getNumOfCalls() < < "次。" < < endl;
  a.show();
  cout < < "a的show()被調(diào)用了:" < < a.getNumOfCalls() < < "次。" < < endl;
  return 0;
}

輸出結(jié)果:

ashow()被調(diào)用了:0次。
data : 1
ashow()被調(diào)用了:1次。

上例void show()const修飾后,導(dǎo)致在該函數(shù)內(nèi)類成員不能被修改,但由于timesmutable修飾后,突破了const的限制,使得times在該函數(shù)內(nèi)部可以被修改。

mutable的另一個(gè)應(yīng)用場(chǎng)景就是用來(lái)移除lambda函數(shù)中按復(fù)制捕獲的形參的const限制。通常情況下(不提供說(shuō)明符),復(fù)制捕獲的對(duì)象在lambda體內(nèi)是 const的,并且在其內(nèi)部無(wú)法修改被捕獲的對(duì)象,具體的例子如下:

#include < iostream >
using namespace std;

int main() {
  int a = 0;
  const int b = 0;

  auto f1 = [=]() {
  /*
  a++;  // 錯(cuò)誤,不提供說(shuō)明符時(shí)復(fù)制捕獲的對(duì)象在 lambda 體內(nèi)是 const 的。
  b++;  // 錯(cuò)誤,同上,且按值傳遞const也會(huì)傳遞進(jìn)來(lái)
  */
    return a;
  };

  auto f2 = [=]() mutable {  // 提供mutable說(shuō)明符
    a++;                     // 正確,mutable解除const限制。
    /*
    b++;  // 錯(cuò)誤,mutable無(wú)法突破b本身的const限制
    */
    return a;
  };

  cout < < a < < ", " < < b < < endl;        // 輸出0, 0
  cout < < f1() < < ", " < < f2() < < endl;  // 輸出0, 1

  return 0;
}

總 結(jié)

const主要用來(lái)告訴編譯器,被修飾的變量是不變類型的,在有些情況下可以對(duì)其進(jìn)行優(yōu)化,同時(shí)如果后面代碼不小心修改了,編譯器在編譯階段報(bào)錯(cuò)。在類的應(yīng)用中,const對(duì)象不能調(diào)用非const成員函數(shù),非const對(duì)象可以調(diào)用const成員函數(shù)。

volatile主要用來(lái)告訴編譯器,被修飾變量是易變,在編譯的時(shí)候不要對(duì)其進(jìn)行優(yōu)化,讀取它的時(shí)候直接從其內(nèi)存地址讀取。

同時(shí),constvolatile限定的引用和指針支持下列的隱式轉(zhuǎn)換:

  • 無(wú)限定類型的引用/指針能被轉(zhuǎn)換成const的引用/指針
  • 無(wú)限定類型的引用/指針能被轉(zhuǎn)換成volatile的引用/指針
  • 無(wú)限定類型的引用/指針能被轉(zhuǎn)換成const volatile的引用/指針
  • const類型的引用/指針能被轉(zhuǎn)換成const volatile的引用/指針
  • volatile 類型的引用/指針能被轉(zhuǎn)換成const volatile的引用/指針

對(duì)于const修飾的成員函數(shù)內(nèi)類成員const的屬性,可以通過(guò)使用對(duì)mutable來(lái)解除const限制。同樣的,mutable也可以用來(lái)移除lambda函數(shù)中按復(fù)制捕獲的形參的const限制。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5357

    瀏覽量

    120592
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    492

    瀏覽量

    27561
  • C++語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    147

    瀏覽量

    7007
  • gcc編譯器
    +關(guān)注

    關(guān)注

    0

    文章

    78

    瀏覽量

    3396
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C語(yǔ)言關(guān)鍵字volatile的用法

    許多程序員都無(wú)法正確理解C語(yǔ)言關(guān)鍵字volatile,這并不奇怪。因?yàn)榇蠖鄶?shù)C語(yǔ)言書(shū)籍通常都是一兩句一帶而過(guò),本文將告訴你如何正確使用它。
    發(fā)表于 04-11 09:35 ?2672次閱讀

    C語(yǔ)言關(guān)鍵字const的幾種用法

    本期來(lái)講解一個(gè)C語(yǔ)言的關(guān)鍵字——const
    發(fā)表于 06-21 11:05 ?1677次閱讀
    <b class='flag-5'>C</b>語(yǔ)言<b class='flag-5'>關(guān)鍵字</b><b class='flag-5'>const</b>的幾種用法

    C++中常用關(guān)鍵字詳解(2)

    C++中,volatile是一個(gè)關(guān)鍵字,用于修飾變量,告訴編譯器該變量的值可能在程序流程之外被意外修改,因此編譯器不應(yīng)該對(duì)該變量進(jìn)行優(yōu)化(如緩存變量值或重排指令順序)。
    發(fā)表于 08-08 16:15 ?356次閱讀

    【原創(chuàng)分享】單片機(jī)編程關(guān)鍵字volatile

    volatile其實(shí)和const一樣是一種類型修飾符,用它修飾的變量表示可以被某些編譯器未知的因素而改變,比如操作系統(tǒng)、硬件或者其他線程等等。遇到這個(gè)關(guān)鍵字聲明的變量,編譯器對(duì)訪問(wèn)該變量的代碼就不再進(jìn)行優(yōu)化
    發(fā)表于 06-29 11:17

    C語(yǔ)言volatile關(guān)鍵字詳解 精選資料分享

    1.volatile和什么有關(guān)百度翻譯是這樣子翻譯volatile的:圖1-1 百度翻譯volatile截圖volatile屬于C語(yǔ)言的
    發(fā)表于 07-22 07:20

    嵌入式程序員常見(jiàn)的const、static、volatile關(guān)鍵字

    嵌入式程序員const、static、volatile三個(gè)關(guān)鍵字的樸素認(rèn)識(shí)摘要:在C語(yǔ)言程序編寫中,const、static
    發(fā)表于 12-21 06:08

    C語(yǔ)言中的volatile關(guān)鍵字

    volatile關(guān)鍵字是一種類型修飾符,用它聲明的類型變量表示可以被某些編譯器未知的因素更改。
    發(fā)表于 05-27 09:32 ?3277次閱讀

    C++Cconst關(guān)鍵字有何差別?

    C++C中的const關(guān)鍵字有何差別?
    的頭像 發(fā)表于 02-03 14:51 ?1826次閱讀

    關(guān)于volatile關(guān)鍵字對(duì)編譯器優(yōu)化的影響

    volatile關(guān)鍵字對(duì)編譯器優(yōu)化的影響
    的頭像 發(fā)表于 02-28 17:15 ?2956次閱讀

    C++中的const和引用的討論

    今天給大家分享一下這段時(shí)間學(xué)習(xí)c++的總結(jié)學(xué)習(xí):c++里面的const關(guān)鍵字和引用。
    的頭像 發(fā)表于 12-24 15:35 ?859次閱讀

    C++mutable關(guān)鍵字詳解與實(shí)戰(zhàn)

    mutable關(guān)鍵字詳解與實(shí)戰(zhàn) 在C++mutable關(guān)鍵字是為了突破
    的頭像 發(fā)表于 09-10 09:23 ?5565次閱讀

    一文詳解volatile關(guān)鍵字

    volatile 是易變的、不穩(wěn)定的意思。和const一樣是一種類型修飾符,volatile關(guān)鍵字修飾的變量,編譯器對(duì)訪問(wèn)該變量的代碼不再進(jìn)行優(yōu)化,從而可以提供對(duì)特殊地址的穩(wěn)定訪問(wèn)。
    的頭像 發(fā)表于 02-15 11:54 ?1078次閱讀
    一文<b class='flag-5'>詳解</b><b class='flag-5'>volatile</b><b class='flag-5'>關(guān)鍵字</b>

    C++中的const關(guān)鍵字介紹

    前一篇文章我們主要介紹了C++中的復(fù)合類型引用和指針,這篇文章我們將會(huì)主要介紹C++const關(guān)鍵字。有時(shí)候我們想定義一個(gè)值不能被改變的變量,例如我們想使用一個(gè)變量存儲(chǔ)buffer的
    的頭像 發(fā)表于 03-17 14:01 ?678次閱讀

    淺談C++mutable關(guān)鍵字

    C++11中推出了一種特殊的關(guān)鍵字mutable用于修飾類變量。它的作用是標(biāo)注該變量一定會(huì)被修改,因此也就不是const類型。目的是為了使這些成員變量在被
    的頭像 發(fā)表于 04-15 11:13 ?3794次閱讀

    const關(guān)鍵字應(yīng)用總結(jié)

    C++中的const關(guān)鍵字的用法非常靈活,而使用const將大大改善程序的健壯性
    的頭像 發(fā)表于 05-26 09:06 ?581次閱讀
    主站蜘蛛池模板: 国产69精品久久久久人妻刘玥| 午夜亚洲动漫精品AV网站| 好看AV中文字幕在线观看| qvod 艺术片| yellow片高清视频免费看| 大陆女人内谢69XXXORG| 国产精品久久久久久久久无码 | 欧美激情一区二区三区视频| 秘密教学26我们在做一次吧免费 | 国产精品内射久久久久欢欢| 国产亚洲人成在线视频 | nxgx69日本护士| 成视频高清| 国产欧美日韩亚洲第一页| 精品国产麻豆AV无码| 伦理电影2499伦理片| 日本成熟bbxxxxxxxx| 香蕉eeww99国产精品| 伊人影院综合在线| 99久女女精品视频在线观看 | 一个人日本的视频免费完整版| 91交换论坛| 国产成人综合在线观看| 精品国产乱码久久久人妻| 免费在线伦理片| 婷婷久久综合九色综合伊人色| 日韩高清在线亚洲专区| 性色爽爱性色爽爱网站| 尤物久久99国产综合精品| xiao776唯美清纯| 国精产品一区一区三区有限在线| 国产午夜小视频| 麻豆一二三区果冻| 色综合久久综合网观看| 一二三四在线播放免费观看中文版视频 | 花蝴蝶在线观看免费8| 男同志vdieos免费| 亚洲AV蜜桃永久无码精品无码网| 2021久久最新国产精品| 国产精品免费视频播放| 免费a视频在线观看|