精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

国产精品igao网网址不卡| 国产中文一区二区| 国产大屁股喷水视频在线观看| eeuss鲁一区二区三区| 成人深夜视频在线观看| 91精品国产91久久久久久不卡| 日本黄色特级片| 成人国产二区| 国产精品国产三级国产aⅴ中文| 成人看片人aa| 国产91av视频| 九九免费精品视频在线观看| 欧美喷水一区二区| 成人av在线播放观看| 水中色av综合| 美女黄网久久| 欧美福利视频在线观看| 亚洲国产欧美视频| 91麻豆精品| 欧美午夜宅男影院在线观看| 国产卡一卡二在线| 日本在线视频1区| 久久99久久久久| 亚洲第一页在线观看| 99热这里只有精品99| 欧美在线三级| 亚洲精品成a人在线观看| 成人性做爰aaa片免费看不忠| 欧美日韩视频精品二区| 国产一区二区精品久久99| 色综合久久天天综线观看| 亚洲熟妇一区二区三区| 日韩欧美高清一区二区三区| 91国在线观看| 精品无码一区二区三区在线| 91在线不卡| av网站免费线看精品| 成人免费福利在线| 秋霞精品一区二区三区| 欧美日韩亚洲一区三区| 中文字幕最新精品| 久久久久久无码精品人妻一区二区| 最新欧美电影| 午夜伦欧美伦电影理论片| 视频一区二区视频| 黄色电影免费在线看| 成人午夜在线视频| 成人写真福利网| 日韩 国产 欧美| 99综合视频| 欧美激情精品久久久久久久变态| 波多野结衣家庭教师在线观看| 婷婷综合福利| 亚洲激情电影中文字幕| 真实乱偷全部视频| 久久电影天堂| 丰满岳妇乱一区二区三区| 男人c女人视频| 黄色大片在线播放| 中文字幕一区二区三区不卡| 色狠狠久久av五月综合| 欧美视频免费一区二区三区| av激情亚洲男人天堂| 97中文在线| 99国产在线播放| 久久99精品久久久久久| 国产精品永久免费| 一级爱爱免费视频| 美日韩一区二区三区| 国产精品成人av在线| 在线观看免费国产视频| 在线亚洲一区| 日本午夜在线亚洲.国产| 国产精品久久久免费视频| 亚洲巨乳在线| 57pao国产精品一区| 国产又大又黄视频| 久久av最新网址| 日本成人在线视频网址| 日日摸天天添天天添破| 99香蕉国产精品偷在线观看| 性欧美亚洲xxxx乳在线观看| 日韩和一区二区| 夜夜爽av福利精品导航| 日本免费在线精品| 亚洲av无码乱码国产精品fc2| 蜜臀av一区二区在线免费观看| 国产精品综合久久久| 国产一区二区视频免费观看| 国产一区二区不卡| 国产亚洲一区二区三区在线播放| 桃花色综合影院| 国产无遮挡一区二区三区毛片日本| 青娱乐一区二区| 成人高清免费在线播放| 中文字幕永久在线不卡| 中文网丁香综合网| 欧美videossex| 午夜精品久久久久久久久久 | 日韩在线免费av| 黄色精品视频在线观看| 成人一区二区| 久久99国产精品久久久久久久久| 中文字幕在线字幕中文| 日韩精品一区第一页| 亚洲综合日韩在线| 神马午夜精品95| 国产欧美日韩激情| 欧美美女黄色网| a一区二区三区| 欧美日韩一区二区三区四区五区| 精品无码av一区二区三区不卡| 欧美一级大片在线视频| 精品中文字幕久久久久久| 一二三四在线观看视频| 亚洲色图88| 日本a级片电影一区二区| 97av免费视频| youjizz国产精品| 午夜精品区一区二区三| 国产精品69xx| 欧美日韩一卡二卡| 91黄色免费视频| 外国成人免费视频| 97在线看福利| av片免费播放| 中文字幕第一区第二区| 青青草视频国产| 精品欧美日韩精品| 亚洲精品美女久久| 九九热最新地址| 日韩中文字幕不卡| 激情久久av| 性欧美ⅴideo另类hd| 欧美性少妇18aaaa视频| 一区二区在线免费观看视频| 日韩一区二区在线| 欧亚精品中文字幕| 亚洲va天堂va欧美ⅴa在线| 国产日韩亚洲欧美综合| 黄色大片在线免费看| 国产视频一区二区在线播放| 亚洲色图五月天| 日韩美女一级片| 国产盗摄精品一区二区三区在线 | 日韩成人av影视| 国产私拍一区| 色呦呦视频在线观看| 欧美精品 国产精品| 草草影院第一页| 伊人久久亚洲热| 亚洲最大av网| www.久久ai| 7777精品伊人久久久大香线蕉| 尤物视频最新网址| aa亚洲婷婷| 国产视频在线观看一区| 色呦呦在线看| 欧美一级淫片007| 久久国产波多野结衣| 蜜桃视频一区二区三区| 日产国产精品精品a∨| 捆绑调教日本一区二区三区| 91精品国产综合久久精品app| 精品熟妇无码av免费久久| 日韩av中文字幕一区二区三区| 蜜桃视频在线观看成人| 小h片在线观看| 精品黑人一区二区三区久久| 欧美日韩在线观看成人| 国产成人小视频| 欧美aaa在线观看| 国产精品成人3p一区二区三区 | 成人写真视频福利网| 精品麻豆一区二区三区| 91精品综合久久久久久| 曰本女人与公拘交酡| 精品在线播放免费| 日本xxx免费| 第四色中文综合网| 亚洲天堂av综合网| 久久免费激情视频| hitomi一区二区三区精品| 黄色一级视频片| 免费欧美视频| 国产精品中文在线| av电影免费在线观看| 精品少妇一区二区三区日产乱码| 国产第一页在线播放| 国产九色精品成人porny| 大陆极品少妇内射aaaaaa| 高潮按摩久久久久久av免费| 久久久久久久香蕉网| 丝袜+亚洲+另类+欧美+变态| 91久久精品网| 国产手机在线观看| 日本aⅴ免费视频一区二区三区 | 亚洲九九视频| 久久影院理伦片| 日韩深夜福利网站| 国内自拍欧美激情| 永久免费av在线| 亚洲福利影片在线| 一级黄色片网站| 欧美日韩国产页| 久久国产波多野结衣| 久久久亚洲综合| 欧美人与性动交α欧美精品| 日韩成人dvd| 每日在线更新av| 综合久久婷婷| 日本一区不卡| 欧美变态挠脚心| 亚洲自拍偷拍区| 国产成人精选| 日韩av色在线| 福利成人导航| 久久九九免费视频| caoporn国产精品免费视频| 精品国产电影一区二区| 国产精品欧美激情在线| 色吊一区二区三区| 成人精品在线看| 亚洲地区一二三色| 亚洲av鲁丝一区二区三区| 国产欧美一区二区三区在线看蜜臀| 亚洲啪av永久无码精品放毛片 | av网站在线免费播放| 亚洲国产天堂久久国产91| wwwav在线播放| 在线不卡中文字幕| 精品国产www| 91久久线看在观草草青青| 日本一区二区免费电影| 亚洲成a人v欧美综合天堂| 日韩欧美综合视频| 中文字幕一区二区三区色视频| 欧美丰满美乳xxⅹ高潮www| 91碰在线视频| 男男做爰猛烈叫床爽爽小说 | 亚洲不卡在线播放| 亚洲欧洲国产专区| 任你操精品视频| 国产精品免费丝袜| 亚洲精品91在线| 久久久久久夜精品精品免费| 欧美熟妇一区二区| 久久亚洲一区二区三区四区| 50一60岁老妇女毛片| 成人精品一区二区三区中文字幕| 香蕉久久久久久av成人| 国产mv日韩mv欧美| 国产精品偷伦视频免费观看了 | 鬼打鬼之黄金道士1992林正英| 日韩成人视屏| 国产一区二区高清不卡| 欧美激情网址| 三区精品视频| 日韩影院二区| 黄色www在线观看| 欧美黄污视频| 欧美视频在线观看视频| 1024日韩| aa免费在线观看| 日本伊人精品一区二区三区观看方式 | yy1111111| 久久男人中文字幕资源站| 变态另类ts人妖一区二区| 国产精品久久免费看| 四虎永久免费地址| 亚洲一区二区三区不卡国产欧美| 天天干在线播放| 欧洲另类一二三四区| 艳妇乳肉豪妇荡乳av| 日韩欧美精品在线| 午夜影院在线视频| 亚洲网站在线看| 免费不卡视频| 久久久久久久香蕉网| 久久爱91午夜羞羞| 国产一区私人高清影院| 亚洲一区二区电影| 欧美一区二区三区四区五区六区| 日韩在线中文| 免费一级淫片aaa片毛片a级| 亚洲综合国产| 精品国产鲁一鲁一区二区三区| 成人激情免费网站| 日本黄色小视频在线观看| 亚洲日本在线观看| 久久精品视频7| 91精品欧美一区二区三区综合在 | 日本a视频在线观看| 久久综合图片| 日韩精品在线播放视频| 26uuu色噜噜精品一区二区| 国精品人伦一区二区三区蜜桃| 亚洲五码中文字幕| 中文字幕理论片| 亚洲国产精品悠悠久久琪琪 | 中文字幕中文字幕一区二区 | 99精品国产在热久久婷婷| 特级丰满少妇一级| 成人av在线播放网站| 欧美自拍偷拍网| 五月天欧美精品| 国产精品毛片一区二区在线看舒淇 | 精品久久中文| a级免费在线观看| 美女视频黄频大全不卡视频在线播放| 黄色av电影网站| 中文字幕一区二区三区色视频| 久久国产黄色片| 精品欧美一区二区久久| 欧美激情办公室videoshd| 青青久久av北条麻妃黑人| 66精品视频在线观看| 亚洲二区自拍| 国产视频一区三区| 自拍一级黄色片| 国产精品丝袜黑色高跟| 久久国产视频一区| 欧美精品一区二区三区高清aⅴ| 香蕉视频国产在线观看| 日本国产一区二区三区| 国产福利一区二区精品秒拍| 天天爱天天做天天操| 蜜臀久久99精品久久久久宅男| mm131美女视频| 无码av免费一区二区三区试看 | 亚洲欧美日韩成人| 国产理论在线| 国产传媒一区二区| 欧美日韩专区| 少妇性l交大片7724com| 亚洲欧洲99久久| 91美女精品网站| 中文字幕在线精品| 91精品国产66| 亚洲巨乳在线观看| 日本欧美久久久久免费播放网| 一本色道久久综合亚洲精品图片| 欧美日韩国产色视频| 亚洲三区在线观看无套内射| 7m第一福利500精品视频| 久久久久久毛片免费看| 欧美午夜小视频| 成人av网址在线| 中国一级特黄毛片| 亚洲精品720p| sm捆绑调教国产免费网站在线观看| 国产经典一区二区三区 | 国产精品不卡视频| 国产老妇伦国产熟女老妇视频| 日韩在线中文字幕| 99视频有精品高清视频| 亚洲精美视频| 精品亚洲成a人在线观看| 欧洲美女女同性互添| 91精品午夜视频| 超碰在线最新网址| 国产亚洲一区二区三区在线播放| 国产麻豆综合| 亚洲精品视频网址| 在线不卡一区二区| 亚洲小说区图片区都市| 国产精品日韩高清| 亚洲中字黄色| 黄色国产在线播放| 欧美一区二区三区日韩| av影片在线| 日韩欧美一区二区在线观看| 久久精品国产一区二区三区免费看 | 爆乳熟妇一区二区三区霸乳| 国产精品天干天干在线综合| av片免费播放| 国产91精品久| 欧美xxxx中国| 韩国三级hd两男一女| 色婷婷精品久久二区二区蜜臀av| 天天在线视频色| 成人在线看片| 日韩不卡在线观看日韩不卡视频| 紧身裙女教师波多野结衣| 亚洲国产精品人人爽夜夜爽| 国精产品一区一区三区四川| 香蕉视频免费版| 91免费观看视频在线| 糖心vlog精品一区二区| 欧美高清激情视频| 国产日韩欧美一区二区三区| 日韩精品在线播放视频| 色综合久久久久久久久久久| 国产三区视频在线观看| 久久久久九九九| 国产一区二区三区在线观看免费| 青青操免费在线视频| 人妻丰满熟妇av无码久久洗澡| 国产一区二区0| 日韩免费在线看|