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

C++模板基礎及代碼實戰

開發 前端
C++ 中支持泛型編程的基本工具是模板。雖然模板不嚴格是面向對象的特性,但它們可以與面向對象編程結合產生強大的效果。

一、C++ 模板概覽

1.泛型編程的支持

C++ 不僅為面向對象編程提供了語言支持,還支持泛型編程。正如第6章《設計可重用性》中討論的,泛型編程的目標是編寫可重用的代碼。C++ 中支持泛型編程的基本工具是模板。雖然模板不嚴格是面向對象的特性,但它們可以與面向對象編程結合產生強大的效果。

2.模板的核心

在過程化編程范式中,主要編程單元是過程或函數。函數之所以有用,主要是因為它們允許你編寫與特定值無關的算法,因此可以用于許多不同的值。例如,C++ 中的 sqrt() 函數計算調用者提供的值的平方根。只計算一個數字(如四)的平方根的函數不會特別有用!sqrt() 函數是針對一個參數編寫的,該參數是調用者傳遞的任何值的代表。

對象導向編程范式增加了對象的概念,對象將相關數據和行為組合在一起,但它并沒有改變函數和方法參數化值的方式。

3.模板的進階參數化

模板將參數化概念進一步擴展,允許你對類型以及值進行參數化。C++ 中的類型包括 int、double 等基本類型,以及 SpreadsheetCell、CherryTree 等用戶定義的類。有了模板,你可以編寫不僅與它將要給定的值無關,而且與這些值的類型無關的代碼。例如,你可以編寫一個堆棧類定義,而不是編寫用于存儲 int、Cars 和 SpreadsheetCells 的單獨堆棧類,這個堆棧類定義可以用于任何這些類型。

4.模板的使用和重要性

盡管模板是一項驚人的語言特性,但 C++ 中的模板在語法上可能令人困惑,許多程序員避免自己編寫模板。然而,每個程序員至少需要知道如何使用模板,因為它們被廣泛用于庫,例如 C++ 標準庫。本章教你如何在 C++ 中支持模板,重點是在標準庫中出現的方面。在此過程中,你將了解一些除了使用標準庫之外,你可以在程序中運用的巧妙特性。

二、類模板

1.類模板的定義和應用

類模板定義了一個類,其中一些變量的類型、方法的返回類型和/或方法的參數被指定為模板參數。類模板主要用于容器,即存儲對象的數據結構。這一節通過運行示例 Grid 容器來說明。為了保持示例的合理長度并足夠簡單以闡明特定要點,本章的不同部分將為 Grid 容器添加不在后續部分使用的功能。

2.編寫類模板

假設你想要一個通用的游戲棋盤類,可以用作國際象棋棋盤、跳棋棋盤、井字棋棋盤或任何其他二維游戲棋盤。為了使其具有通用性,你應該能夠存儲國際象棋棋子、跳棋棋子、井字棋棋子或任何類型的游戲棋子。

三、不使用模板編寫代碼

1.通過多態性建立通用游戲棋盤

在沒有模板的情況下,構建通用游戲棋盤的最佳方法是使用多態性來存儲通用的 GamePiece 對象。然后,你可以讓每個游戲的棋子從 GamePiece 類繼承。例如,在國際象棋游戲中,ChessPiece 將是 GamePiece 的派生類。通過多態性,編寫為存儲 GamePiece 的 GameBoard 也可以存儲 ChessPiece。因為可能需要復制 GameBoard,所以 GameBoard 需要能夠復制 GamePiece。這種實現使用多態性,所以一種解決方案是在 GamePiece 基類中添加一個純虛擬的 clone() 方法,派生類必須實現它以返回具體 GamePiece 的副本。

這是基本的 GamePiece 接口:

export class GamePiece {
public:
    virtual ~GamePiece() = default;
    virtual std::unique_ptr<GamePiece> clone() const = 0;
};

GamePiece 是一個抽象基類。具體類,如 ChessPiece,從它派生并實現 clone() 方法:

class ChessPiece : public GamePiece {
public:
    std::unique_ptr<GamePiece> clone() const override {
        // 調用復制構造函數來復制這個實例
        return std::make_unique<ChessPiece>(*this);
    }
};

2.GameBoard 的實現

GameBoard 的實現使用向量的向量和 unique_ptr 來存儲 GamePieces:

GameBoard::GameBoard(size_t width, size_t height) : m_width { width }, m_height { height } {
    m_cells.resize(m_width);
    for (auto& column : m_cells) {
        column.resize(m_height);
    }
}

GameBoard::GameBoard(const GameBoard& src) : GameBoard { src.m_width, src.m_height } {
    // The ctor-initializer of this constructor delegates first to the
    // non-copy constructor to allocate the proper amount of memory.
    // The next step is to copy the data.
    for (size_t i { 0 }; i < m_width; i++) {
        for (size_t j { 0 }; j < m_height; j++) {
            if (src.m_cells[i][j]) {
                m_cells[i][j] = src.m_cells[i][j]->clone();
            }
        }
    }
}

void GameBoard::verifyCoordinate(size_t x, size_t y) const {
    if (x >= m_width) {
        throw out_of_range { format("{} must be less than {}.", x, m_width) };
    }
    if (y >= m_height) {
        throw out_of_range { format("{} must be less than {}.", y, m_height) };
    }
}

void GameBoard::swap(GameBoard& other) noexcept {
    std::swap(m_width, other.m_width);
    std::swap(m_height, other.m_height);
    std::swap(m_cells, other.m_cells);
}

void swap(GameBoard& first, GameBoard& second) noexcept {
    first.swap(second);
}

GameBoard& GameBoard::operator=(const GameBoard& rhs) {
    // Copy-and-swap idiom
    GameBoard temp { rhs }; // Do all the work in a temporary instance.
    swap(temp); // Commit the work with only non-throwing operations.
    return *this;
}

const unique_ptr<GamePiece>& GameBoard::at(size_t x, size_t y) const {
    verifyCoordinate(x, y);
    return m_cells[x][y];
}

unique_ptr<GamePiece>& GameBoard::at(size_t x, size_t y) {
    return const_cast<unique_ptr<GamePiece>&>(as_const(*this).at(x, y));
}

在這個實現中,at() 返回指定位置的棋子的引用,而不是棋子的副本。GameBoard 作為二維數組的抽象,應該通過給出索引處的實際對象而不是對象的副本來提供數組訪問語義。

3.注意事項

這個實現為 at() 提供了兩個版本,一個返回非常量引用,另一個返回常量引用。

使用復制和交換習語(copy-and-swap idiom)用于賦值運算符,以及 Scott Meyer 的 const_cast() 模式來避免代碼重復。

4.GameBoard 類的使用

GameBoard chessBoard { 8, 8 };
auto pawn { std::make_unique<ChessPiece>() };
chessBoard.at(0, 0) = std::move(pawn);
chessBoard.at(0, 1) = std::make_unique<ChessPiece>();
chessBoard.at(0, 1) = nullptr;

這個 GameBoard 類運行得相當好,它可以用于國際象棋棋盤的創建和棋子的放置。

四、類模板實現的 Grid 類

1.GameBoard 的局限性

在上一節中的 GameBoard 類雖然實用,但有其局限性。首先,你無法使用 GameBoard 來按值存儲元素;它總是存儲指針。更嚴重的問題與類型安全有關。GameBoard 中的每個單元格都存儲一個 unique_ptr<GamePiece>。即使你存儲的是 ChessPieces,當你使用 at() 請求特定單元格時,你將得到一個 unique_ptr<GamePiece>。這意味著你必須將檢索到的 GamePiece 向下轉型為 ChessPiece 才能使用 ChessPiece 的特定功能。GameBoard 的另一個缺點是它不能用于存儲原始類型,如 int 或 double,因為單元格中存儲的類型必須派生自 GamePiece。

2.實現通用 Grid 類

因此,如果你能編寫一個通用的 Grid 類來存儲 ChessPieces、SpreadsheetCells、ints、doubles 等就很好了。在 C++ 中,你可以通過編寫類模板來實現這一點,這允許你編寫一個不指定一個或多個類型的類。然后客戶端通過指定他們想要使用的類型來實例化模板。這就是所謂的泛型編程。

3.泛型編程的優勢

泛型編程的最大優勢是類型安全。類及其方法中使用的類型是具體類型,而不是像上一節中多態解決方案那樣的抽象基類類型。例如,假設不僅有 ChessPiece,還有 TicTacToePiece:

class TicTacToePiece : public GamePiece {
public:
    std::unique_ptr<GamePiece> clone() const override {
        // 調用復制構造函數來復制這個實例
        return std::make_unique<TicTacToePiece>(*this);
    }
};

使用上一節中的多態解決方案,沒有什么能阻止你在同一個棋盤上存儲井字棋棋子和國際象棋棋子:

GameBoard chessBoard { 8, 8 };
chessBoard.at(0, 0) = std::make_unique<ChessPiece>();
chessBoard.at(0, 1) = std::make_unique<TicTacToePiece>();

這樣做的一個大問題是,你需要記住一個單元格存儲了什么,以便在調用 at() 時執行正確的向下轉型。

五、Grid 類模板的定義

1.類模板的語法

為了理解類模板,檢查其語法非常有幫助。以下示例展示了如何將 GameBoard 類修改為模板化的 Grid 類。代碼后面會詳細解釋語法。請注意,類名已從 GameBoard 改為 Grid。

2.使用值語義實現 Grid 類

與 GameBoard 實現中使用的多態指針語義相比,我選擇使用值語義而不是多態來實現這個解決方案。m_cells 容器存儲實際對象,而不是指針。與指針語義相比,使用值語義的一個缺點是不能有真正的空單元格;也就是說,單元格必須始終包含某個值。使用指針語義時,空單元格存儲 nullptr。 std::optional 在這里提供了幫助。它允許你在仍然有表示空單元格的方法的同時使用值語義。

template <typename T>
class Grid {
public:
    explicit Grid(size_t width = DefaultWidth, size_t height = DefaultHeight);
    virtual ~Grid() = default;

    // Explicitly default a copy constructor and assignment operator.
    Grid(const Grid& src) = default;
    Grid& operator=(const Grid& rhs) = default;

    // Explicitly default a move constructor and assignment operator.
    Grid(Grid&& src) = default;
    Grid& operator=(Grid&& rhs) = default;

    std::optional<T>& at(size_t x, size_t y);
    const std::optional<T>& at(size_t x, size_t y) const;

    size_t getHeight() const { return m_height; }
    size_t getWidth() const { return m_width; }

    static const size_t DefaultWidth { 10 };
    static const size_t DefaultHeight { 10 };

private:
    void verifyCoordinate(size_t x, size_t y) const;

    std::vector<std::vector<std::optional<T>>> m_cells;
    size_t m_width { 0 }, m_height { 0 };
};

3.類模板的詳細解讀

export template <typename T>:這一行表示接下來的類定義是一個關于類型 T 的模板,并且它正在從模塊中導出。template 和 typename 是 C++ 中的關鍵字。如前所述,模板在類型上“參數化”,就像函數在值上“參數化”一樣。

使用模板類型參數名(如 T)來表示調用者將作為模板類型參數傳遞的類型。T 的名稱沒有特殊含義——你可以使用任何你想要的名稱。

4.關于模板類型參數的注意事項

出于歷史原因,你可以使用關鍵字 class 而不是 typename 來指定模板類型參數。因此,許多書籍和現有程序使用類似 template <class T> 的語法。然而,在這種情況下使用 class 這個詞是令人困惑的,因為它暗示類型必須是一個類,這實際上并不正確。類型可以是類、結構體、聯合、語言的原始類型,如 int 或 double 等。

六、Grid 類模板與 GameBoard 類的對比

1.數據成員的變化

在之前的 GameBoard 類中,m_cells 數據成員是指針的向量的向量,這需要特殊的復制代碼,因此需要拷貝構造函數和拷貝賦值操作符。在 Grid 類中,m_cells 是可選值的向量的向量,所以編譯器生成的拷貝構造函數和賦值操作符是可以的。

2.顯式默認構造函數和操作符

一旦你有了用戶聲明的析構函數,就不推薦編譯器隱式生成拷貝構造函數或拷貝賦值操作符,因此 Grid 類模板顯式地將它們默認化。它還顯式默認化了移動構造函數和移動賦值操作符。以下是顯式默認的拷貝賦值操作符:

Grid& operator=(const Grid& rhs) = default;

可以看到,rhs 參數的類型不再是 const GameBoard&,而是 const Grid&。在類定義內,編譯器會在需要時將 Grid 解釋為 Grid<T>,但如果你愿意,也可以顯式地使用 Grid<T>:

Grid<T>& operator=(const Grid<T>& rhs) = default;

然而,在類定義外,你必須使用 Grid<T>。當你編寫類模板時,你過去認為的類名(Grid)實際上是模板名。當你想談論實際的 Grid 類或類型時,你必須使用模板 ID,即 Grid<T>,這些是針對特定類型(如 int、SpreadsheetCell 或 ChessPiece)的 Grid 類模板的實例化。

3.at() 方法的更新

由于 m_cells 不再存儲指針,而是存儲可選值,at() 方法現在返回 std::optional<T> 而不是 unique_ptrs,即可以有類型 T 的值,也可以為空的 optionals:

std::optional<T>& at(size_t x, size_t y);
const std::optional<T>& at(size_t x, size_t y) const;

七、Grid 類模板的方法定義

1.模板方法定義格式

每個 Grid 模板的方法定義都必須以 template <typename T> 說明符開頭。構造函數如下所示:

template <typename T>
Grid<T>::Grid(size_t width, size_t height) : m_width { width }, m_height { height } {
    m_cells.resize(m_width);
    for (auto& column : m_cells) {
        column.resize(m_height);
    }
}

注意:類模板的方法定義需要對使用該類模板的任何客戶端代碼可見。這對方法定義的位置施加了一些限制。通常,它們直接放在類模板定義本身的同一文件中。本章后面討論了繞過這一限制的一些方法。

2.類名和方法定義

請注意,:: 前的類名是 Grid<T>,而不是 Grid。在所有方法和靜態數據成員定義中,你必須指定 Grid<T> 作為類名。構造函數的主體與 GameBoard 構造函數相同。其他方法定義也類似于 GameBoard 類中的對應方法,但有適當的模板和 Grid<T> 語法變化:

template <typename T>
void Grid<T>::verifyCoordinate(size_t x, size_t y) const {
    if (x >= m_width) {
        throw std::out_of_range { std::format("{} must be less than {}.", x, m_width) };
    }
    if (y >= m_height) {
        throw std::out_of_range { std::format("{} must be less than {}.", y, m_height) };
    }
}

template <typename T>
const std::optional<T>& Grid<T>::at(size_t x, size_t y) const {
    verifyCoordinate(x, y);
    return m_cells[x][y];
}

template <typename T>
std::optional<T>& Grid<T>::at(size_t x, size_t y) {
    return const_cast<std::optional<T>&>(std::as_const(*this).at(x, y));
}

3.類模板方法的默認值

注意:如果類模板方法的實現需要某個模板類型參數的默認值(例如 T),則可以使用 T{} 語法。T{} 調用對象的默認構造函數(如果 T 是類類型),或生成零(如果 T 是基本類型)。這種語法稱為零初始化語法。它是為尚不知道類型的變量提供合理默認值的好方法。

八、使用 Grid 類模板

1.模板實例化

當你想要創建 Grid 對象時,不能單獨使用 Grid 作為類型;你必須指定將存儲在該 Grid 中的類型。為特定類型創建類模板對象稱為實例化模板。以下是一個示例:

Grid<int> myIntGrid; // 聲明一個存儲 int 的網格,使用構造函數的默認參數。
Grid<double> myDoubleGrid { 11, 11 }; // 聲明一個 11x11 的 double 類型網格。
myIntGrid.at(0, 0) = 10;
int x { myIntGrid.at(0, 0).value_or(0) };
Grid<int> grid2 { myIntGrid }; // 拷貝構造函數
Grid<int> anotherIntGrid;
anotherIntGrid = grid2; // 賦值操作符

請注意 myIntGrid、grid2 和 anotherIntGrid 的類型是 Grid<int>。你不能在這些網格中存儲 SpreadsheetCells 或 ChessPieces;如果嘗試這樣做,編譯器將生成錯誤。

2.使用 value_or()

還要注意 value_or() 的使用。at() 方法返回一個可選引用,可能包含值也可能不包含。value_or() 方法在可選項中有值時返回該值;否則,它返回給 value_or() 的參數。

3.模板類型的重要性

模板類型的指定非常重要;以下兩行都無法編譯:

Grid test; // 無法編譯
Grid<> test; // 無法編譯

如果你想聲明一個接受 Grid 對象的函數或方法,你必須在 Grid 類型中指定存儲在網格中的類型:

void processIntGrid(Grid<int>& grid) { /* 省略正文以簡潔 */ }

或者,你可以使用本章后面討論的函數模板,編寫一個模板化的函數,該函數根據網格中元素的類型進行模板化。

注意:你可以使用類型別名來簡化完整的 Grid 類型的重復書寫,例如 Grid<int>:

using IntGrid = Grid<int>;void processIntGrid(IntGrid& grid) { /* 正文 */ }

4.Grid 類模板的多樣性

Grid 類模板可以存儲的不僅僅是 int。例如,你可以實例化一個存儲 SpreadsheetCells 的 Grid:

Grid<SpreadsheetCell> mySpreadsheet;
SpreadsheetCell myCell { 1.234 };
mySpreadsheet.at(3, 4) = myCell;

你也可以存儲指針類型:

Grid<const char*> myStringGrid;
myStringGrid.at(2, 2) = "hello";

指定的類型甚至可以是另一個模板類型:

Grid<vector<int>> gridOfVectors;
vector<int> myVector { 1, 2, 3, 4 };
gridOfVectors.at(5, 6) = myVector;

你還可以在自由存儲區動態分配 Grid 模板實例:

auto myGridOnFreeStore { make_unique<Grid<int>>(2, 2) }; // 自由存儲區上的 2x2 網格。
myGridOnFreeStore->at(0, 0) = 10;
int x { myGridOnFreeStore->at(0, 0).value_or(0) };
責任編輯:趙寧寧 來源: coding日記
相關推薦

2010-02-06 16:59:19

C++ kmp算法模板

2010-02-05 17:58:32

C++鏈棧模板

2010-02-04 13:45:36

C++類模板

2023-12-18 11:15:03

2011-07-15 00:47:13

C++多態

2011-07-14 17:45:06

CC++

2023-12-13 10:51:49

C++函數模板編程

2011-07-13 18:24:18

C++

2020-07-30 12:40:35

CC++編程語言

2010-02-03 17:42:33

C++模板參數

2023-10-30 10:29:50

C++最小二乘法

2010-01-26 13:55:07

C++標準模板庫

2022-09-22 10:22:36

C++編程語言代碼

2010-01-13 10:31:35

C++代碼

2010-01-14 14:40:21

C++代碼

2010-01-18 16:17:53

C++代碼

2010-02-06 09:53:26

C++ void

2011-06-21 10:00:21

預處理指令

2011-05-31 17:59:48

C++

2011-05-18 18:05:47

C#C++
點贊
收藏

51CTO技術棧公眾號

潘金莲激情呻吟欲求不满视频| 91精品久久久久久久久久入口| 国产精品扒开腿做爽爽爽a片唱戏| 国产黄色大片在线观看| av午夜一区麻豆| 97国产精品视频人人做人人爱| 偷拍女澡堂一区二区三区| jizzyou欧美16| 夜夜亚洲天天久久| 欧美精品七区| 精品人妻aV中文字幕乱码色欲| 亚洲日本黄色| 成人97在线观看视频| 国产精品一级黄片| 动漫一区二区三区| 一本高清dvd不卡在线观看| 青春草在线视频免费观看| 无码精品黑人一区二区三区| 精品一区二区三区av| 欧美一区第一页| 欧美h片在线观看| 女人av一区| 亚洲精品在线观看视频| 欧美特黄aaa| 欧美大片1688| 狠狠色噜噜狠狠狠狠97| 一区二区三区观看| 色视频在线观看福利| 激情小说亚洲一区| 国产精品欧美激情| 激情视频网站在线观看| 亚洲午夜伦理| 超碰日本道色综合久久综合| av男人的天堂av| 欧美色图婷婷| 精品国产凹凸成av人网站| 久久久久久久久久一区| 91福利精品在线观看| 激情成人在线视频| 日韩美女爱爱视频| dy888亚洲精品一区二区三区| 国产亚洲精品免费| 国产成人看片| 亚洲第一天堂网| 国产在线精品国自产拍免费| 国产精品视频一区二区三区四| 中文字幕超碰在线| 99在线|亚洲一区二区| 欧美激情欧美狂野欧美精品| 91麻豆精品成人一区二区| 秋霞欧美视频| 在线视频免费一区二区| jizz中文字幕| 九九久久电影| 亚洲男人的天堂在线| 波多野结衣影院| 久久草在线视频| 亚洲精品理论电影| 天天插天天射天天干| 另类在线视频| 亚洲精品视频中文字幕| 四虎永久免费影院| 奇米亚洲欧美| 一道本无吗dⅴd在线播放一区| 亚洲激情视频小说| 精品视频亚洲| 久久精品国产久精国产一老狼 | 亚洲成人av片在线观看| 国产清纯白嫩初高中在线观看性色| 久久一级大片| 欧美mv日韩mv| 欧洲一级黄色片| 亚洲国产欧美日韩在线观看第一区| 亚洲精品短视频| 国精产品一区一区三区免费视频 | 精品日本一线二线三线不卡| 香蕉视频1024| 久本草在线中文字幕亚洲| 日韩av网站电影| 国内精品卡一卡二卡三| 久久影视一区| 欧美裸体男粗大视频在线观看| 免费在线看黄网址| 亚洲精品欧洲| 国产精品国模在线| 国产精品一区二区黑人巨大 | 色偷偷成人一区二区三区91| 91制片厂毛片| 日韩高清一区| 日韩极品精品视频免费观看| 高潮毛片无遮挡| 久久综合av| 欧美激情久久久| 亚洲欧美一区二区三区在线观看| 精品一区免费av| 国产精品乱码| 午夜毛片在线| 亚洲国产精品尤物yw在线观看| 免费在线激情视频| 91精品一区| 亚洲第一色中文字幕| 精品人伦一区二区三电影| 天天综合国产| 91精品国产精品| ,一级淫片a看免费| 91性感美女视频| 亚洲精品国产一区| wwwwxxxx在线观看| 欧美日韩国产在线播放网站| 成人区人妻精品一区二| 成人动漫免费在线观看| 久久青草精品视频免费观看| 天天干天天插天天射| 国产91综合网| 一区二区三区在线视频看| 91桃色在线观看| 欧美日韩国产片| 少妇饥渴放荡91麻豆| 亚洲精品va| 国产精品劲爆视频| 无码精品一区二区三区在线| 自拍偷拍国产亚洲| 日本成人在线免费视频| 成人av综合网| 日韩视频在线观看免费| 三级视频在线观看| 成人sese在线| 50度灰在线观看| 欧美日韩破处视频| 亚洲性生活视频| 天天操天天操天天操天天| 国产剧情在线观看一区二区| 日韩av电影免费在线观看| 91美女精品| 精品少妇一区二区三区在线播放| 国产喷水在线观看| 日韩—二三区免费观看av| 精品免费国产| 高清毛片在线观看| 亚洲国产精品成人va在线观看| 欧美精品久久久久久久久46p| 日韩福利视频网| 日韩精品久久久免费观看| 亚洲天堂av在线| 日韩av一区在线观看| 日本在线视频免费| 成人动漫精品一区二区| 国产不卡一区二区视频| 99ri日韩精品视频| 欧美疯狂性受xxxxx另类| 99国产精品久久久久久久成人| 国产精品久久久久久一区二区三区| 白嫩少妇丰满一区二区| 精品国产乱码久久久久久1区2匹| 热久久免费视频精品| 婷婷亚洲一区二区三区| 狠狠久久五月精品中文字幕| 欧美 日本 国产| 羞羞答答国产精品www一本 | 黄色av网站免费在线观看| 亚洲另类一区二区| 在线观看你懂的视频| 欧美在线二区| 成人看片视频| 黑森林国产精品av| 精品亚洲一区二区三区四区五区| 亚洲另类欧美日韩| 久久久美女毛片 | 老司机精品视频导航| 亚洲永久激情精品| 国产精品1区在线| 久久99视频精品| 蜜桃视频久久一区免费观看入口| 亚洲国产综合视频在线观看| 制服丝袜第二页| 天堂成人国产精品一区| 亚洲欧美日韩精品在线| 国产美女亚洲精品7777| 欧美激情视频网| 三级视频网站在线| 欧美日韩视频第一区| 国产午夜精品理论片在线| 国产成人精品亚洲午夜麻豆| 青青青国产在线观看| 国产成人精品999在线观看| 国产精品美女免费| 三级福利片在线观看| 日韩国产精品亚洲а∨天堂免| 国产精品无码粉嫩小泬| 亚洲欧美日韩综合aⅴ视频| 秋霞午夜鲁丝一区二区| 亚洲少妇一区| 亚洲精品影院| 亚洲视频国产精品| 国产成人在线视频| 一色桃子av在线| 亚洲美女在线观看| 国产精品一区二区三区在线免费观看| 亚洲综合成人网| 精品无码国产污污污免费网站| 国内欧美视频一区二区| 久久国产亚洲精品无码| 我不卡神马影院| 国内不卡一区二区三区| 欧美成人aaa| 91av国产在线| 中文字幕在线三区| 亚洲欧美国产日韩中文字幕| 国产xxxx在线观看| 色婷婷综合久久久| 欧美人妻精品一区二区三区 | 麻豆视频在线免费看| 99re这里只有精品首页| 亚洲高清在线不卡| 免费在线欧美黄色| 91免费版看片| 日韩在线综合| 麻豆久久久av免费| 亚洲精品午夜| 国产精品永久免费在线| av3级在线| 欧美噜噜久久久xxx| av一区在线观看| 亚洲精品日韩久久久| www.五月激情| 欧美猛男超大videosgay| 永久免费无码av网站在线观看| 亚洲一本大道在线| 国模无码国产精品视频| 国产精品素人视频| 性猛交ⅹxxx富婆video| 99国产精品视频免费观看| 色婷婷狠狠18禁久久| 激情国产一区二区| 国产美女18xxxx免费视频| 免费黄网站欧美| 天堂社区在线视频| 首页亚洲欧美制服丝腿| 大肉大捧一进一出好爽视频| 激情欧美一区二区三区| 日韩久久久久久久久久久久| 中文字幕免费一区二区| 中文字幕精品一区日韩| 成人网18免费网站| 四虎影院一区二区三区 | 亚洲精品电影网| 欧洲av在线播放| 精品国精品国产尤物美女| 999av视频| 日韩一级免费观看| 精品人妻无码一区二区| 91精品国产综合久久福利| 国产精品视频无码| 91麻豆精品国产91久久久久久| 欧美男人天堂网| 欧美性生活影院| 伊人久久国产精品| 欧美群妇大交群的观看方式| 亚洲中文字幕一区二区| 91 com成人网| 亚洲第一视频在线| 亚洲精品美女在线观看播放| 亚洲 欧美 激情 另类| 国产午夜精品久久久| 国产日本在线观看| xvideos亚洲人网站| 最新av在线播放| 欧美激情视频在线观看| 9999热视频在线观看| 日本精品一区二区三区在线播放视频| 三上悠亚激情av一区二区三区 | www.一区二区.com| 亚洲麻豆视频| 白嫩少妇丰满一区二区| 麻豆精品视频在线观看| 日本wwwxx| 91视频一区二区| 国产成人福利在线| 亚洲精品视频在线观看网站| 国产无遮挡裸体免费视频| 日韩欧美高清视频| 夜夜嗨aⅴ一区二区三区| 欧美成人精品福利| 欧洲亚洲在线| 久久亚洲成人精品| 狠狠操一区二区三区| 国产精品视频地址| 亚洲一区二区三区日本久久九| 久久久久久九九| 久久精品高清| 日韩成人手机在线| 日本欧美一区二区| 一级黄色免费毛片| 91久色porny| 性生交大片免费全黄| 婷婷久久综合九色综合伊人色| 最近中文字幕在线观看视频| 日韩一区二区三区视频在线| 日韩私人影院| 欧美日韩成人在线播放| 欧美一级大黄| 91在线精品观看| 国内精品久久久久久99蜜桃| 加勒比海盗1在线观看免费国语版| 亚洲欧美久久久| 可以看的av网址| 国产欧美视频一区二区| 五月天综合在线| 欧美精品在线观看播放| 天堂а在线中文在线无限看推荐| 久久久91精品| 日本久久免费| 国产精品久久久久久免费观看| 日韩精品永久网址| 中文字幕无码精品亚洲35| 麻豆精品国产传媒mv男同| 亚洲欧美视频在线播放| 亚洲欧美日本在线| 亚洲欧美日韩一区二区三区四区| 精品福利一区二区三区免费视频| 天天在线视频色| 奇米一区二区三区四区久久| xvideos.蜜桃一区二区| 美国av在线播放| 日韩高清不卡一区二区三区| 人妻熟女aⅴ一区二区三区汇编| 亚洲激情综合网| 一卡二卡在线观看| 中文字幕欧美亚洲| 四虎4545www精品视频| 精品一区二区国产| 欧美日韩一视频区二区| 日韩精品aaa| 国产精品乱人伦一区二区| jizz国产在线| 亚洲三级黄色在线观看| 忘忧草在线日韩www影院| 国产精品一区二区免费| 亚洲成人资源| 久久久久久婷婷| 午夜视频一区在线观看| 亚洲av无码国产综合专区| 久久综合国产精品台湾中文娱乐网| 91福利精品在线观看| 神马欧美一区二区| 先锋亚洲精品| 色无极影院亚洲| 日韩欧美主播在线| 国产综合视频一区二区三区免费| 日本一欧美一欧美一亚洲视频| 日韩av资源网| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 91小视频在线免费看| 九九精品免费视频| 亚洲桃花岛网站| 欧美日韩在线精品一区二区三区激情综合| 免费看国产精品一二区视频| 久久久久久网| 成人在线观看免费高清| 欧美色图天堂网| 久久久久久国产精品免费无遮挡| 成人女保姆的销魂服务| 欧美久久视频| 久久久午夜精品福利内容| 欧美日韩国产激情| 韩国福利在线| 国产日韩欧美日韩| 欧美一区二区三区另类| 久久久久久久久久影视| 精品久久久国产| 国内av一区二区三区| 国产伦精品一区二区三区精品视频| 手机在线电影一区| 国产麻豆剧传媒精品国产| 五月综合激情婷婷六月色窝| 免费a级毛片在线观看| 91精品久久久久久久久久另类 | 国产日韩精品一区二区三区在线| 亚洲欧美日韩一区二区三区四区| 日韩有码在线观看| 91精品尤物| 无码人妻丰满熟妇区毛片18| 国产精品理论片在线观看| 亚洲AV无码精品国产| 全亚洲最色的网站在线观看| 久久高清免费| 91精品啪在线观看国产| 欧美亚洲图片小说| 欧美巨大xxxx做受沙滩| 欧美日韩精品一区| 国产一区二三区好的| 天天操天天摸天天干| 日韩在线中文字| 免费看久久久| 成年网站免费在线观看| 亚欧色一区w666天堂| 1769在线观看| 精品亚洲欧美日韩| 国产一区二区看久久| 日日夜夜操视频|