精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入理解C++20:類與對象的高級特性及運算符重載

開發 前端
就像基本的算術運算符一樣,C++20之前的六個比較運算符應該是全局函數,這樣你可以在運算符的左右兩邊的參數上使用隱式轉換。

類與對象的高級特性

1.常量靜態數據成員

在你的類中,可以聲明 const 數據成員,這意味著它們在創建和初始化后不能被改變。當常量僅適用于類時,應該使用 static const(或 const static)數據成員來代替全局常量,這也稱為類常量。整型和枚舉類型的 static const 數據成員即使不將它們作為內聯變量,也可以在類定義內部定義和初始化。例如,你可能想要為Spreadsheet指定一個最大高度和寬度。如果用戶嘗試構造一個高度或寬度超過最大值的Spreadsheet,將使用最大值代替。你可以將最大高度和寬度作為 Spreadsheet 類的 static const 成員:

export class Spreadsheet {
public:
    // 省略簡略性
    static const size_t MaxHeight { 100 };
    static const size_t MaxWidth { 100 };
};

你可以在構造函數中使用這些新常量,如下所示:

Spreadsheet::Spreadsheet(size_t width, size_t height)
    : m_id { ms_counter++ },
      m_width { min(width, MaxWidth) } // std::min() 需要 <algorithm>
      m_height { min(height, MaxHeight) }
{
    // 省略簡略性
}

注意,你也可以選擇在寬度或高度超過最大值時拋出異常,而不是自動將寬度和高度限制在其最大值內。但是,當你從構造函數中拋出異常時,析構函數將不會被調用,所以你需要小心處理這一點。這在第14章詳細討論了錯誤處理。

2.數據成員的不同種類

此類常量也可以用作參數的默認值。記住,你只能為從最右邊參數開始的一連串參數提供默認值。這里有一個例子:

export class Spreadsheet {
public:
    Spreadsheet(size_t width = MaxWidth, size_t height = MaxHeight);
    // 省略簡略性
};

3.引用數據成員

Spreadsheet和 SpreadsheetCells 很棒,但它們本身并不構成一個有用的應用程序。你需要代碼來控制整個Spreadsheet程序,你可以將其打包到一個名為 SpreadsheetApplication 的類中。假設我們希望每個 Spreadsheet 都存儲對應用程序對象的引用。SpreadsheetApplication 類的確切定義此刻并不重要,因此下面的代碼簡單地將其定義為一個空類。Spreadsheet 類被修改為包含一個新的引用數據成員,稱為 m_theApp:

export class SpreadsheetApplication {
};

export class Spreadsheet {
public:
    Spreadsheet(size_t width, size_t height, SpreadsheetApplication& theApp);
    // 省略簡略性
private:
    // 省略簡略性
    SpreadsheetApplication& m_theApp;
};

這個定義為數據成員添加了一個 SpreadsheetApplication 引用。建議在這種情況下使用引用而不是指針,因為 Spreadsheet 應該總是引用一個 SpreadsheetApplication,而指針則不能保證這一點。請注意,將應用程序的引用存儲起來僅是為了演示引用作為數據成員的用法。不建議以這種方式將 Spreadsheet 和 SpreadsheetApplication 類耦合在一起,而是使用模型-視圖-控制器(MVC)范例。

在其構造函數中,應用程序引用被賦給每個 Spreadsheet。引用不能存在而不指向某些東西,因此 m_theApp 必須在構造函數的 ctor-initializer 中被賦值:

Spreadsheet::Spreadsheet(size_t width, size_t height, SpreadsheetApplication& theApp)
    : m_id { ms_counter++ },
      m_width { std::min(width, MaxWidth) },
      m_height { std::min(height, MaxHeight) },
      m_theApp { theApp }
{
    // 省略簡略性
}

你還必須在拷貝構造函數中初始化引用成員。這是自動處理的,因為 Spreadsheet 拷貝構造函數委托給非拷貝構造函數,后者初始化了引用數據成員。記住,一旦你初始化了一個引用,你就不能改變它所引用的對象。在賦值操作符中不可能對引用進行賦值。根據你的用例,這可能意味著你的類不能為含有引用數據成員的類提供賦值操作符。如果是這種情況,賦值操作符通常被標記為刪除。

最后,引用數據成員也可以標記為 const。例如,你可能決定 Spreadsheets 只應該對應用程序對象有一個常量引用。你可以簡單地更改類定義,將 m_theApp 聲明為對常量的引用:

export class Spreadsheet {
public:
    Spreadsheet(size_t width, size_t height, const SpreadsheetApplication& theApp);
    // 省略簡略性
private:
    // 省略簡略性
    const SpreadsheetApplication& m_theApp;
};

3.嵌套類

類定義不僅可以包含成員函數和數據成員,還可以編寫嵌套類和結構體,聲明類型別名或創建枚舉類型。在類內部聲明的任何內容都在該類的作用域內。如果它是公開的,你可以通過使用類名加上作用域解析運算符(ClassName::)來在類外部訪問它。

例如,你可能會決定 SpreadsheetCell 類實際上是 Spreadsheet 類的一部分。由于它成為 Spreadsheet 類的一部分,你可能會將其重命名為 Cell。你可以像這樣定義它們:

export class Spreadsheet {
public:
    class Cell {
    public:
        Cell() = default;
        Cell(double initialValue);
        // 省略簡略性
    };
    
    Spreadsheet(size_t width, size_t height, const SpreadsheetApplication& theApp);
    // 省略其他 Spreadsheet 聲明
};

現在,Cell 類在 Spreadsheet 類內部定義,所以在 Spreadsheet 類外部引用 Cell 時,你必須使用 Spreadsheet:: 作用域來限定名稱。這甚至適用于方法定義。例如,Cell 的雙精度構造函數現在看起來像這樣:

Spreadsheet::Cell::Cell(double initialValue)
    : m_value { initialValue } {
}

即使是在 Spreadsheet 類本身的方法的返回類型(但不是參數)中,也必須使用此語法:

Spreadsheet::Cell& Spreadsheet::getCellAt(size_t x, size_t y) {
    verifyCoordinate(x, y);
    return m_cells[x][y];
}

直接在 Spreadsheet 類內部完全定義嵌套的 Cell 類會使 Spreadsheet 類的定義變得臃腫。你可以通過僅在 Spreadsheet 類中包含 Cell 的前向聲明,然后分別定義 Cell 類來緩解這種情況:

export class Spreadsheet {
public:
    class Cell;
    Spreadsheet(size_t width, size_t height, const SpreadsheetApplication& theApp);
    // 省略其他 Spreadsheet 聲明
};

class Spreadsheet::Cell {
public:
    Cell() = default;
    Cell(double initialValue);
    // 省略簡略性
};

普通的訪問控制適用于嵌套類定義。如果你聲明了一個私有或受保護的嵌套類,你只能從外部類內部使用它。嵌套類可以訪問外部類的所有受保護和私有成員。而外部類只能訪問嵌套類的公共成員。

4.類內部的枚舉類型

枚舉類型也可以是類的數據成員。例如,你可以添加對 SpreadsheetCell 類的單元格著色支持,如下所示:

export class SpreadsheetCell {
public:
    // 省略簡略性
    
    enum class Color {
        Red = 1, Green, Blue, Yellow
    };
    
    void setColor(Color color);
    Color getColor() const;
    
private:
    // 省略簡略性
    Color m_color { Color::Red };
};

setColor() 和 getColor() 方法的實現很直接:

void SpreadsheetCell::setColor(Color color) {
    m_color = color;
}

SpreadsheetCell::Color SpreadsheetCell::getColor() const {
    return m_color;
}

新方法的使用方式如下:

SpreadsheetCell myCell { 5 };
myCell.setColor(SpreadsheetCell::Color::Blue);
auto color { myCell.getColor() };

運算符重載

你經常需要對對象執行操作,例如添加它們、比較它們,或將它們流入流出文件。例如,Spreadsheet只有在你可以對其執行算術操作時才有用,比如求一整行單元格的和。

1.重載比較運算符

在你的類中定義比較運算符,如>、<、<=、>=、==和!=,是非常有用的。C++20標準為這些運算符帶來了很多變化,并增加了三元比較運算符,即太空船運算符<=>,在第1章中有介紹。為了更好地理解C++20所提供的內容,讓我們先來看看在C++20之前你需要做些什么,以及在你的編譯器還不支持三元比較運算符時你仍需要做些什么。

就像基本的算術運算符一樣,C++20之前的六個比較運算符應該是全局函數,這樣你可以在運算符的左右兩邊的參數上使用隱式轉換。比較運算符都返回一個布爾值。當然,你可以更改返回類型,但這并不推薦。這里是聲明,你需要用==、<、>、!=、<=和>=替換<op>,從而產生六個函數:

export class SpreadsheetCell { /* 省略以便簡潔 */ };
export bool operator<op>(const SpreadsheetCell& lhs, const SpreadsheetCell& rhs);

以下是operator==的定義。其他的定義類似。

bool operator==(const SpreadsheetCell& lhs, const SpreadsheetCell& rhs) {
    return (lhs.getValue() == rhs.getValue());
}

注意:前述重載的比較運算符正在比較雙精度值。大多數時候,對浮點值進行等于或不等于測試并不是一個好主意。你應該使用所謂的epsilon測試,但這超出了本書的范圍。在具有更多數據成員的類中,比較每個數據成員可能很痛苦。然而,一旦你實現了==和<,你就可以用這兩個運算符來寫其它的比較運算符。例如,這里是一個使用operator<的operator>=定義:

bool operator>=(const SpreadsheetCell& lhs, const SpreadsheetCell& rhs) {
    return !(lhs < rhs);
}

你可以使用這些運算符來比較SpreadsheetCells與其他SpreadsheetCells,也可以與雙精度和整型比較:

if (myCell > aThirdCell || myCell < 10) {
    cout << myCell.getValue() << endl;
}

正如你所見,你需要編寫六個不同的函數來支持六個比較運算符,這只是為了比較兩個SpreadsheetCells。隨著當前六個實現的比較函數,可以將SpreadsheetCell與一個雙精度值進行比較,因為雙精度參數被隱式轉換為SpreadsheetCell。如前所述,這種隱式轉換可能效率低下,因為需要創建臨時對象。就像之前的operator+一樣,你可以通過實現顯式函數來避免與雙精度的比較。對于每個運算符<op>,你將需要以下三個重載:

bool operator<op>(const SpreadsheetCell& lhs, const SpreadsheetCell& rhs);
bool operator<op>(double lhs, const SpreadsheetCell& rhs);
bool operator<op>(const SpreadsheetCell& lhs, double rhs);

如果你想支持所有比較運算符,那么需要編寫很多重復的代碼!

2.C++20

現在讓我們轉換一下思路,看看C++20帶來了什么。C++20極大地簡化了為你的類添加比較運算符的支持。首先,使用C++20,實際上建議將operator==實現為類的成員函數,而不是全局函數。還要注意,添加[[nodiscard]]屬性是個好主意,這樣運算符的結果就不能被忽略了。這里是一個例子:

[[nodiscard]] bool operator==(const SpreadsheetCell& rhs) const;

使用C++20,這一個operator==重載就可以使以下比較工作:

if (myCell == 10) {
    cout << "myCell == 10\n";
}
if (10 == myCell) {
    cout << "10 == myCell\n";
}

例如10==myCell這樣的表達式會被C++20編譯器重寫為myCell==10,可以調用operator==成員函數。此外,通過實現operator==,C++20會自動增加對!=的支持。

接下來,為了實現對完整套比較運算符的支持,在C++20中你只需要實現一個額外的重載運算符,即operator<=>。一旦你的類有了operator==和<=>的重載,C++20會自動為所有六個比較運算符提供支持!對于SpreadsheetCell類,operator<=>如下所示:

[[nodiscard]] std::partial_ordering operator<=>(const SpreadsheetCell& rhs) const;

注意:C++20編譯器不會用<=>重寫==或!=比較,這是為了避免性能問題,因為顯式實現operator==通常比使用<=>更高效。

SpreadsheetCell中存儲的值是一個雙精度值。請記住,從第1章開始,浮點類型只有部分排序,這就是為什么重載返回std::partial_ordering。實現很簡單:

std::partial_ordering SpreadsheetCell::operator<=>(const SpreadsheetCell& rhs) const {
    return getValue() <=> rhs.getValue();
}

通過實現operator<=>,C++20會自動為>、`<、<=和>=提供支持,通過將使用這些運算符的表達式重寫為使用<=>的表達式。例如,類似于myCell<aThirdCell的表達式會自動重寫為類似于std::is_ lt(myCell<=>aThirdCell)的東西,其中is_lt()是一個命名比較函數;所以,通過只實現operator==和operator<=>`,SpreadsheetCell類支持完整的比較運算符集:

if (myCell < aThirdCell) {
    // ...
}
if (aThirdCell < myCell) {
    // ...
}
if (myCell <= aThirdCell) {
    // ...
}
if (aThirdCell <= myCell) {
    // ...
}
if (myCell > aThirdCell) {
    // ...
}
if (aThirdCell > myCell) {
    // ...
}
if (myCell >= aThirdCell) {
    // ...
}
if (aThirdCell >= myCell) {
    // ...
}
if (myCell == aThirdCell) {
    // ...
}
if (aThirdCell == myCell) {
    // ...
}
if (myCell != aThirdCell) {
    // ...
}
if (aThirdCell != myCell) {
    // ...
}

由于SpreadsheetCell類支持從雙精度到SpreadsheetCell的隱式轉換,因此也支持以下比較:

if (myCell < 10) {
}
if (10 < myCell) {
}
if (10 != myCell) {
}

就像比較兩個SpreadsheetCell對象一樣,編譯器會將這些表達式重寫為使用operator==和<=>的形式,并根據需要交換參數的順序。例如,10<myCell首先被重寫為類似于is_lt(10<=>myCell)的東西,這不會起作用,因為我們只有<=>作為成員的重載,這意味著左側參數必須是SpreadsheetCell。注意到這一點后,編譯器再嘗試將表達式重寫為類似于is_gt(myCell<=>10)的東西,這就可以工作了。與以前一樣,如果你想避免隱式轉換的輕微性能影響,你可以為雙精度提供特定的重載。而這現在,多虧了C++20,甚至不是很多工作。你只需要提供以下兩個額外的重載運算符作為方法:

[[nodiscard]] bool operator==(double rhs) const;
[[nodiscard]] std::partial_ordering operator<=>(double rhs) const;

這些實現如下:

bool SpreadsheetCell::operator==(double rhs) const {
    return getValue() == rhs;
}
std::partial_ordering SpreadsheetCell::operator<=>(double rhs) const {
    return getValue() <=> rhs;
}

2.編譯器生成的比較運算符

在查看SpreadsheetCell的operator和<=>的實現時,可以看到它們只是簡單地比較所有數據成員。在這種情況下,我們可以進一步減少編寫代碼的行數,因為C++20可以為我們完成這些工作。就像可以顯式默認化拷貝構造函數一樣,operator和<=>也可以被默認化,這種情況下編譯器將為你編寫它們,并通過依次比較每個數據成員來實現它們。此外,如果你只顯式默認化operator<=>,編譯器還會自動包含一個默認的operator。因此,對于沒有顯式operator和<=>用于雙精度的SpreadsheetCell版本,我們可以簡單地編寫以下單行代碼,為比較兩個SpreadsheetCell添加對所有六個比較運算符的完全支持:

[[nodiscard]] std::partial_ordering operator<=>(const SpreadsheetCell&) const = default;

此外,你可以將operator<=>的返回類型使用auto,這種情況下編譯器會基于數據成員的<=>運算符的返回類型來推斷返回類型。如果你的類有不支持operator<=>的數據成員,那么返回類型推斷將不起作用,你需要顯式指定返回類型為strong_ordering、partial_ordering或weak_ordering。為了讓編譯器能夠編寫默認的<=>運算符,類的所有數據成員都需要支持operator<=>,這種情況下返回類型可以是auto,或者是operator<和==,這種情況下返回類型不能是auto。由于SpreadsheetCell有一個雙精度數據成員,編譯器推斷返回類型為partial_ordering。

[[nodiscard]] auto operator<=>(const SpreadsheetCell&) const = default;

單獨的顯式默認化的operator<=>適用于沒有顯式operator==和<=>用于雙精度的SpreadsheetCell版本。如果你添加了這些顯式的雙精度版本,你就添加了一個用戶聲明的operator==(double)。因為這個原因,編譯器將不再自動生成operator==(const SpreadsheetCell&),所以你必須自己顯式默認化一個,如下所示:

export class SpreadsheetCell {
public:
    // Omitted for brevity
    [[nodiscard]] auto operator<=>(const SpreadsheetCell&) const = default;
    [[nodiscard]] bool operator==(const SpreadsheetCell&) const = default;
    [[nodiscard]] bool operator==(double rhs) const;
    [[nodiscard]] std::partial_ordering operator<=>(double rhs) const;
    // Omitted for brevity
};

如果你的類可以顯式默認化operator<=>,我建議這樣做,而不是自己實現它。通過讓編譯器為你編寫,它將隨著新添加或修改的數據成員保持最新狀態。如果你自己實現了運算符,那么每當你添加數據成員或更改現有數據成員時,你都需要記得更新你的operator<=>實現。如果operator==沒有被編譯器自動生成,同樣的規則也適用于它。只有當它們作為參數有對類類型的引用時,才能顯式默認化operator==和<=>。例如,以下不起作用:

[[nodiscard]] auto operator<=>(double) const = default; // 不起作用!

注意:要在C++20中向類添加對所有六個比較運算符的支持: ? 如果默認化的operator<=>適用于你的類,那么只需要一行代碼顯式默認化operator<=>作為方法即可。在某些情況下,你可能需要顯式默認化operator==。 ? 否則,只需重載并實現operator==和<=>作為方法。無需手動實現其他比較運算符。

責任編輯:趙寧寧 來源: coding日記
相關推薦

2023-11-22 13:40:17

C++函數

2024-07-12 15:46:58

2009-08-12 10:47:03

C#運算符重載

2009-08-12 12:46:11

C#運算符重載

2009-08-12 10:27:12

C#運算符重載運算符重載實例

2009-08-14 10:16:57

C#運算符重載

2009-09-04 13:18:10

C#允許運算符重載

2009-08-12 10:56:47

C#運算符重載C#運算符重載實例

2023-11-20 22:19:10

C++static

2020-11-26 14:05:39

C ++運算符數據

2024-04-10 12:14:36

C++指針算術運算

2021-12-15 10:25:57

C++運算符重載

2011-07-15 01:34:36

C++重載運算符

2024-01-26 16:37:47

C++運算符開發

2009-08-12 10:37:13

C#運算符重載

2021-12-16 10:40:11

C++運算符重載

2009-08-12 11:20:51

C#運算符重載

2020-09-30 14:04:25

C++運算符重載

2020-08-10 10:20:15

流插入運算符語言

2020-12-26 16:51:12

Python操作符開發
點贊
收藏

51CTO技術棧公眾號

亚洲国产一区二区精品视频| 992tv在线成人免费观看| 五月婷婷六月合| 麻豆网站在线免费观看| 国产sm精品调教视频网站| 国语自产精品视频在线看一大j8| 国产男男chinese网站| 日韩成人免费av| 亚洲午夜激情av| 日本高清不卡一区二区三| av观看在线免费| 国产精品嫩草99av在线| 日韩中文在线中文网三级| 337p日本欧洲亚洲大胆张筱雨| 亚洲人成在线网站| 亚洲欧美在线另类| 精品人伦一区二区三区| 91成人国产综合久久精品| 国产精品久久久亚洲一区| 日韩中文字幕在线免费观看| www.日本高清| 另类视频一区二区三区| 色狠狠av一区二区三区| 台湾无码一区二区| 91在线不卡| 97国产精品videossex| 91情侣偷在线精品国产| 久久这里只有精品9| 精品成人一区| 久久久国产在线视频| 国产精品国产三级国产专业不| 91精品久久久久久综合五月天| 欧美视频一区二区三区在线观看| 男女超爽视频免费播放| av小次郎在线| 中文字幕一区二区三区在线播放 | 亚洲一区二区在线免费观看| 好吊色一区二区| 韩国v欧美v日本v亚洲v| 国产精品www网站| 亚洲影院在线播放| 国产精品视区| 午夜精品福利电影| 国产性生活网站| 欧美日韩久久| 久久久国产一区二区三区| 顶级黑人搡bbw搡bbbb搡| 欧美在线色图| 亚洲色图狂野欧美| 在线观看国产网站| 亚洲aaa级| 亚洲高清一区二| av黄色一级片| 欧美精品中文| 亚洲精品美女网站| 中文字幕丰满孑伦无码专区| 麻豆一区一区三区四区| 亚洲高清免费观看高清完整版| 91亚洲一线产区二线产区 | 国产一区二区三区四区五区加勒比| 国产精品综合在线| 国产一区二区精品久久91| 成人做爽爽免费视频| 97在线播放免费观看| 久久91精品久久久久久秒播| 成人美女免费网站视频| 99久久精品免费看国产交换| 国产精品资源在线观看| 99视频免费观看蜜桃视频| 亚洲AV无码一区二区三区少妇| 国产成人a级片| 高清视频在线观看一区| 天天射天天操天天干| 2欧美一区二区三区在线观看视频| 玛丽玛丽电影原版免费观看1977| 免费在线黄色影片| 国产精品你懂的在线| av不卡在线免费观看| 色黄网站在线观看| 红桃视频成人在线观看| 日韩一级片播放| 国产美女精品视频免费播放软件| 日韩欧美精品在线视频| 国产网站无遮挡| 成人一区二区| 欧美日本中文字幕| 国产www在线| 蜜桃久久精品一区二区| 成人av男人的天堂| 亚洲人午夜射精精品日韩| 国产精品欧美综合在线| a级免费在线观看| 日本欧美日韩| 日韩欧美中文字幕精品| 精品人妻一区二区三区日产乱码卜| 禁果av一区二区三区| 久久亚洲电影天堂| 成人免费看片98欧美| 秋霞成人午夜伦在线观看| 97netav| 欧美少妇另类| 亚洲免费观看在线视频| 十八禁视频网站在线观看| 9999精品视频| 亚洲日本中文字幕| 私库av在线播放| 天堂影院一区二区| 99超碰麻豆| 97视频在线观看网站| 五月婷婷久久丁香| 欧美一级xxxx| 免费看成人哺乳视频网站| 久久综合伊人77777蜜臀| 国产成人在线视频观看| 国产不卡视频在线观看| 五月天亚洲综合| 成人免费视屏| 五月激情综合网| 特级黄色片视频| 欧美色就是色| 91精品国产91久久久久福利| 国产色综合视频| 高清av一区二区| 在线丝袜欧美日韩制服| 中文字幕人成乱码在线观看| 精品国产人成亚洲区| 欧美a级片免费看| 久久亚洲美女| 国产乱码精品一区二区三区中文 | 国产成人夜色高潮福利影视| 久久精品国产视频| 中国女人一级一次看片| 26uuu亚洲综合色| 欧美性潮喷xxxxx免费视频看| 亚洲男女网站| 中文字幕日韩精品在线| 免费看一级视频| 99久久精品国产一区| 97超碰国产精品| 精品一区二区三区中文字幕| 日韩视频在线免费| 中文字幕一二三四| 国产人伦精品一区二区| 日本wwww视频| 窝窝社区一区二区| 91精品国产色综合久久不卡98| 韩国av免费在线观看| 亚洲免费av观看| 欧美性猛交xx| 欧美午夜影院| 国产偷久久久精品专区| 爱情岛论坛亚洲品质自拍视频网站| 日韩你懂的在线观看| 超碰手机在线观看| 国产传媒欧美日韩成人| 97av中文字幕| 精品少妇一区| 69久久夜色精品国产69| 美女做暖暖视频免费在线观看全部网址91 | 日日噜噜夜夜狠狠视频欧美人| 蜜桃导航-精品导航| 快播电影网址老女人久久| 亚洲欧美国产另类| 中文字幕码精品视频网站| 中文字幕一区三区| 亚洲一二区在线观看| 午夜精品久久| 精品国产综合久久| 成人一区福利| 色噜噜久久综合伊人一本| 国产精品无码一区二区桃花视频| 一区二区三区在线视频观看58| 亚洲欧美综合视频| 香蕉久久夜色精品国产| 日韩一二三区不卡在线视频| 青青青国产精品| 欧美区二区三区| 青青草娱乐在线| 欧美三级日韩三级| 欧美三级小视频| 91碰在线视频| 九九热精品国产| 激情五月***国产精品| 欧美连裤袜在线视频| 欧美一区二区三区婷婷| 欧美精品精品精品精品免费| 免费毛片在线| 制服丝袜亚洲播放| 日本熟妇毛耸耸xxxxxx| 国产人久久人人人人爽| 九九九久久久久久久| 一区二区三区精品视频在线观看| 亚洲国产日韩欧美| 成人午夜网址| 国产精品视频在线播放| 后进极品白嫩翘臀在线播放| 国产一区二区三区中文| 亚洲国产精品欧美久久| 在线视频你懂得一区| 九九免费精品视频| 国产欧美日本一区二区三区| 年下总裁被打光屁股sp| 奇米四色…亚洲| 男的插女的下面视频| 日本一二区不卡| 九色91视频| 国产精品一区二区三区四区在线观看| 91高清视频在线免费观看| a级影片在线| 国产香蕉一区二区三区在线视频 | 亚洲国产高清福利视频| 国产一区二区在线视频观看| 色老汉av一区二区三区| 久久国产一级片| 国产精品久久久久影院老司 | 欧美日韩在线免费播放| 一区免费在线| 丰满人妻一区二区三区53号| 精品国产欧美日韩| 麻豆精品传媒视频| 高潮按摩久久久久久av免费| 92看片淫黄大片欧美看国产片| 深夜成人福利| 91高清视频在线免费观看| 欧美人与禽性xxxxx杂性| 久久天堂电影网| 成年午夜在线| 国产亚洲人成网站在线观看| 视频福利在线| 亚洲а∨天堂久久精品9966| 精品国产一级片| 欧美高清一级片在线| 天天干天天插天天射| 欧美视频中文字幕在线| 日韩免费在线视频观看| 亚洲午夜久久久久久久久电影院 | 牛牛澡牛牛爽一区二区| 亚洲国内高清视频| 东京干手机福利视频| 欧美一区二区精品在线| 国产情侣激情自拍| 56国语精品自产拍在线观看| 一级片视频网站| 欧美天天综合网| 精品乱码一区内射人妻无码 | 国产女同91疯狂高潮互磨| 欧美伊人久久久久久久久影院| 免费黄色片视频| 色欧美片视频在线观看| 无码人妻精品一区二区三区不卡| 尤物视频一区二区| 国产又粗又硬视频| 2023国产精品自拍| 国产精品成人一区二区三区电影毛片 | 亚洲欧美一区二区在线观看| 亚洲一级片在线播放| 国产精品黄色在线观看| 蜜桃av.com| 亚洲欧美日韩国产一区二区三区| 伊人久久久久久久久久久久久久| 亚洲天堂成人网| 亚洲色婷婷一区二区三区| 亚洲夂夂婷婷色拍ww47| 久久综合成人网| 欧美日韩精品在线| 中文人妻av久久人妻18| 欧美色图第一页| 国产视频手机在线| 精品成人佐山爱一区二区| 三区在线观看| 综合国产在线观看| 91麻豆一二三四在线| 97精品伊人久久久大香线蕉| 亚洲天堂av影院| 国产精品黄页免费高清在线观看| 国产欧美自拍| 99视频在线| 亚洲欧洲免费| 色香蕉在线观看| 国内精品福利| 免费观看成人网| 国产一区二区三区黄视频| 尤物网站在线观看| 国产欧美日韩精品a在线观看| 国产高潮流白浆| 精品久久中文字幕久久av| 波多野结衣 久久| 欧美三级电影精品| 成人午夜免费福利| 国产亚洲欧洲高清| 日本aa在线| 国产mv免费观看入口亚洲| 精品中文字幕一区二区三区四区| 久草精品电影| 羞羞色午夜精品一区二区三区| 欧美爱爱视频免费看| 美女视频黄久久| 国产激情第一页| 国产精品电影院| 亚洲精品国产精品乱码| 欧美日韩国产另类不卡| 日本成人一区| 欧美精品在线观看91| 国产成人精品123区免费视频| 亚洲在线观看视频| 精品一区二区三| 久久男人资源站| 久久精品理论片| 最近中文字幕无免费| 亚洲私人影院在线观看| 日韩不卡在线播放| 精品少妇一区二区三区在线视频| av免费在线一区二区三区| 国外视频精品毛片| 成人污污视频| 欧美日韩一区二区视频在线| 欧美a级片一区| 色播五月综合网| 91在线看国产| 国产无遮挡又黄又爽| 91精品国产一区二区人妖| 国产片在线观看| 国产91成人video| 91精品国产自产在线丝袜啪| 中文字幕人成一区| 蜜臀91精品一区二区三区 | 欧美国产欧美亚州国产日韩mv天天看完整 | 亚洲免费专区| 欧美变态另类刺激| 成人短视频下载| 久久久久无码国产精品| 7777精品伊人久久久大香线蕉的| 国产小视频在线播放| 欧美在线视频免费| 红杏aⅴ成人免费视频| 成人av在线播放观看| 国产乱码字幕精品高清av| 日日操免费视频| 欧美制服丝袜第一页| 欧美老女人性开放| 26uuu久久噜噜噜噜| 欧美男人操女人视频| 欧美成人三级在线视频| 成人午夜看片网址| xxxxxx国产| 精品国产乱码久久久久久久| 欧美1234区| 国产精品日韩一区二区| 亚洲看片免费| 亚洲久久久久久| 激情成人在线视频| 亚洲欧美自偷自拍| 欧洲成人在线视频| 精品国内自产拍在线观看视频 | 精品国产乱码久久久久久蜜臀| 2021国产在线| 国产精品乱子乱xxxx| 91久久亚洲| 无码熟妇人妻av| 欧美又粗又大又爽| 久久综合之合合综合久久| 91夜夜未满十八勿入爽爽影院 | 久久精品一区二区三区不卡| 久久青青草原亚洲av无码麻豆 | 男人影院在线观看| 成人在线视频网站| 欧美日本不卡高清| 亚洲自拍偷拍精品| 日韩欧美极品在线观看| www.久久热.com| 亚洲一区二区自拍| 最新日韩av| 成人无码av片在线观看| 欧美日本韩国一区| 国产盗摄精品一区二区酒店| 精品国产一区二区三区四区vr| 首页欧美精品中文字幕| 成年人二级毛片| 亚洲第一中文字幕在线观看| 国产精品av一区二区三区 | 91九色单男在线观看| 狠狠综合久久av一区二区老牛| 亚洲永久无码7777kkk| 欧美日韩在线播放| 国产亚av手机在线观看| 日本成人黄色免费看| 国产伦精品一区二区三区视频青涩 | 国内精品久久久久久久久| 在线日韩一区| 婷婷激情小说网| 欧美性色19p| 黄色网页在线观看| 国内精品视频在线播放| 青青草国产成人av片免费| 激情综合网五月天| 99在线热播精品免费| 亚洲制服中文字幕| 黄色成人av在线| 久cao在线| 六十路精品视频|