青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

聚星亭

吾笨笨且懶散兮 急須改之而奮進(jìn)
posts - 74, comments - 166, trackbacks - 0, articles - 0
  C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

當(dāng)我們?cè)絹?lái)越多的使用C++的特性將越來(lái)越多的問(wèn)題和事物抽象成對(duì)象時(shí), 我們不難發(fā)現(xiàn):很多對(duì)象都具有共性。 比如 數(shù)值可以增加、減少;字符串也可以增加減少。 它們的動(dòng)作是相似的, 只是對(duì)象的類(lèi)型不同而已。

C++ 提供了“模板”這一特性, 可以將“類(lèi)型” 參數(shù)化, 使得編寫(xiě)的代碼更具有通用性。 因此大家都稱模板編程為 “通用編程”或 “泛型編程”。

一般而言, 模板分為 函數(shù)模板 和 類(lèi)模板,下面就讓我們分別來(lái)了解一下它們。

一、 函數(shù)模板

1、 函數(shù)模板的定義和使用

定義一個(gè)模板函數(shù)的格式并不復(fù)雜, 如下:

template <模板參數(shù)列表>

返回類(lèi)型 函數(shù)名(函數(shù)參數(shù)列表)

{

    // code ...

}

下面, 讓我們來(lái)舉一個(gè)例子來(lái)說(shuō)明 模板函數(shù)的作用和用法(具體代碼見(jiàn) Exp01)。

// 定義一個(gè)函數(shù)模板, 用來(lái)實(shí)現(xiàn)任意類(lèi)型數(shù)據(jù)的相互交換。

template <typename T> // 聲明一個(gè) 數(shù)據(jù)類(lèi)型, 此類(lèi)型隨 調(diào)用方 類(lèi)型的變化而變化

void swap(T& a, T& b)

{

    T tmp = a; 

    a = b;

    b = tmp;

}

  

上面的代碼, 說(shuō)明了模板函數(shù)的用法。下面再給出調(diào)用的代碼, 我們看看如何使用這個(gè)函數(shù)模板:

int main(int argc, char* argv[])

{

    int nNum1 = 50;

    int nNum2 = 30;

    double dfNum1 = 2.1;

    double dfNum2 = 3.0;

    char *pszFirst = "Hello ";

    char *pszSec = "world!";

    swap <int> (nNum1, nNum2); // swap函數(shù)模板實(shí)例化為 int類(lèi)型的模板函數(shù)再調(diào)用

    printf("nNum1 = %d, nNum2 = %d\r\n", nNum1, nNum2);

    swap<double> (dfNum1, dfNum2);

    printf("dfNum1 = %f, pszSec = %f\r\n", dfNum1, dfNum2);

    swap<char *> (pszFirst, pszSec);

    printf("pszFirst = %s, pszSec = %s\r\n", pszFirst, pszSec);

return 0;

}

具體的執(zhí)行結(jié)果如下:

我相信,如果你是第一次見(jiàn)到模板的代碼,那你一定也會(huì)像我一樣好奇,這個(gè)功能是怎么實(shí)現(xiàn)的,它是怎么做到讓一段代碼來(lái)兼容各種類(lèi)型的呢?

當(dāng)我要反匯編該EXE得時(shí)候,無(wú)意間查看了下編程生成的map文件,讓我看到了如下的內(nèi)容:

  Address                           

Publics by Value

Rva+Base

Lib:Object

0001:00000140

?swap@@YAXAAH0@Z

00401140 f i

Exp01.obj

0001:00000190

?swap@@YAXAAN0@Z

00401190 f i

Exp01.obj

0001:000001f0

?swap@@YAXAAPAD0@Z

004011f0 f i

Exp01.obj

由此可見(jiàn), 我們編寫(xiě)的void swap(T& a, T& b), 只是一個(gè)“函數(shù)模板”, 要使用它需要先將它實(shí)例化為一個(gè)“模板函數(shù)”(如:swap <int>)。編譯器在編譯此程序的時(shí)候,為每個(gè)調(diào)用此模板的代碼生成了一個(gè)函數(shù)。而且在后期的使用過(guò)程中,更加讓我認(rèn)識(shí)到:

a、 函數(shù)模板 并不是函數(shù),它僅在編譯時(shí)根據(jù)調(diào)用此模板函數(shù)時(shí)傳遞的實(shí)參類(lèi)型來(lái)生成具體的函數(shù)體!若 函數(shù)模板沒(méi)有被調(diào)用責(zé)不生成任何代碼也不對(duì)模板代碼作任何語(yǔ)法檢查。

b、 在模板類(lèi)型參數(shù)中, 實(shí)參與形參要求嚴(yán)格匹配,它不會(huì)進(jìn)行任何的類(lèi)型轉(zhuǎn)換。

c、 對(duì)于函數(shù)模板,我們?cè)谡{(diào)用時(shí)不一定必須先進(jìn)行將它實(shí)例化為一個(gè)函數(shù)也是可以的,編譯器會(huì)自動(dòng)的識(shí)別模板的類(lèi)型。(換句話說(shuō):Exp01中的代碼可以直接使用swap, 而不需要<>

2、  函數(shù)模板的重載

當(dāng)編寫(xiě)的一個(gè)模板無(wú)法滿足所有需要的情況時(shí),就需要對(duì)模板進(jìn)行重載(或叫 特例化),例如:我們編寫(xiě)了一個(gè)較大值的模板Max

template <typename T>

T constMax(T const& a, T const& b)

{

    return a < b ? b : a;

}

A、 當(dāng)我們需要傳入兩個(gè)指針類(lèi)型的實(shí)參時(shí),該模板就失效了,需要重載該模板:

template <typename T>

T constMax(T* const& a, T* const& b)

{

    return *a < *b ? *b : *a;

}

B、 倘若我們?cè)傩枰容^兩個(gè)字符串大小時(shí),上面兩個(gè)模板都失效了。因?yàn)?font face="Times New Roman">char* 并沒(méi)有提供 operator < 運(yùn)行,我們只能通過(guò)調(diào)用strcmp庫(kù)函數(shù)自己實(shí)現(xiàn)一個(gè)Max模板的特例(見(jiàn)Exp02):

const charMax(const char*& a, const char*& b)

{

    return strcmp(a, b) < 0 ? b : a;

}

說(shuō)明:

C++模板機(jī)制規(guī)定,如果一個(gè)調(diào)用,即匹配普通函數(shù),又能匹配模板函數(shù)的話,則優(yōu)先匹配普通函數(shù)。因此,當(dāng)我們模板特例化的時(shí)候,會(huì)先匹配特例化的函數(shù)。

二、 類(lèi)模板

1、  基本概念

類(lèi)模板一般應(yīng)用于容器類(lèi)中,使得容器能夠處理各種類(lèi)型的對(duì)象,如(詳見(jiàn)Exp03):

struct Node

{

   Nodeint nData = 0 )

   {

      m_nData = nData;

      m_pPrev = m_pNext = NULL;

   }

   int   m_nData; // 數(shù)據(jù)元素

   Node* m_pPrev; // 指向上一個(gè)元素的指針

   Node* m_pNext; // 指向下一個(gè)元素的指針

};

class CDList

{

private:

  int  m_nCount;

  Node* m_pHead;

  Node* m_pTail;

  int    m_nMessage;

public:

CDList();

virtual ~CDList();

public:

int GetLen() const

{

m_nCount;

}

NodeGetHead() const

{

return m_pHead;

}

NodeGetTail() const

{

return m_pTail;

}

public:

bool Change(int nIndex1,int nIndex2);

void Release();

//增加

NodeAddTailint nData );

NodeAddHeadint nData );

Nodeoperator[](int nIndex);

//刪除

bool DeleteNodeint nIndex );

void PrintAll();

//查找

NodeFindNodeint nIndex );

};

對(duì)于這樣的鏈表,其節(jié)點(diǎn)的元素只能存放整型數(shù)據(jù)。如果要想讓此雙向鏈表能夠存放任何一種類(lèi)型的元素,那此時(shí)我們需要的問(wèn)題與函數(shù)模板就一樣了,將此類(lèi)修改成類(lèi)模板,現(xiàn)在先不管類(lèi)模板的寫(xiě)法,讓我們按照函數(shù)模板的方法將類(lèi)修改一下:

template <typename T>

struct Node

{

   Node( T Data )

   {

      m_Data  = Data;

      m_pPrev = m_pNext = NULL;

   }

   T m_Data;  /通用類(lèi)型的數(shù)據(jù)元素

   Node<T>* m_pPrev; // 指向上一個(gè)元素的指針

   Node<T>* m_pNext; // 指向下一個(gè)元素的指針

};

這樣,我們每個(gè)節(jié)點(diǎn)都可以使用通用的類(lèi)型了,當(dāng)然,對(duì)節(jié)點(diǎn)的處理也一樣得處理。按照這個(gè)樣子將類(lèi)型參數(shù)化(為節(jié)省篇幅,具體的實(shí)現(xiàn)部分請(qǐng)參考Exp04):

template <typename T>

class CDList

{

private:

int     m_nMessage; // 消息號(hào)

int     m_nCount; // 鏈表中 元素的數(shù)量

Node<T>* m_pHead; // 鏈表頭指針

Node<T>* m_pTail; // 鏈表尾指針

public:

CDList();

virtual ~CDList();

public:

int GetLen() const

{

m_nCount;

}

Node<T>* GetHead() const

{

return m_pHead;

}

Node<T>* GetTail() const

{

return m_pTail;

}

public:

bool Change(int nIndex1,int nIndex2);

void Release();

//增加

Node<T>* AddTail( T Data );

Node<T>* AddHead( T Data );

Node<T>* operator[](int nIndex);

//刪除

bool DeleteNode( int nIndex );

void PrintAll();

//查找

Node<T>* FindNode( int nIndex );

};

這樣就修改好了,很簡(jiǎn)單吧,貌似類(lèi)模板沒(méi)有什么太多的新語(yǔ)法規(guī)范。完整的模板代碼,大家可以參考Exp04,下面我們總結(jié)一下類(lèi)模板的一些語(yǔ)法小細(xì)節(jié)。

2、  類(lèi)模板的定義

通過(guò)上面的一番修改,我相信你一定對(duì)類(lèi)模板有了一定的了解,下面我們大致的總結(jié)一下類(lèi)模板的定義格式:

Template <typename T>

Class 類(lèi)名

{

// code,可以使用模板參數(shù)T來(lái)指定通用的數(shù)據(jù)類(lèi)型。

}

正如上面的Exp04中一樣,我們的模板寫(xiě)好了,但是它不能直接使用,就像函數(shù)模板一樣,我們需要先將模板實(shí)例化成一個(gè)模板類(lèi)才可以使用。在函數(shù)模板中,編譯器會(huì)針對(duì)我們傳遞的實(shí)參類(lèi)型等信息自動(dòng)的給我們實(shí)例化函數(shù)模板為模板函數(shù),但是類(lèi)模板就沒(méi)有這么智能了,必須手工實(shí)例化:

int main(int argc, char* argv[])

{

CDList<int> MyList; // CDList實(shí)例化為一個(gè)int類(lèi)型,也就是說(shuō)鏈表中數(shù)據(jù)元素為整型

//(20) (80) 100 200 50 60

MyList.AddTail(20);

MyList.AddTail(80);

MyList.AddTail(100);

MyList.AddTail(200);

MyList.AddTail(50);

MyList.AddTail(60);

MyList.PrintAll();

MyList.Change(0,1);

MyList.PrintAll();

return 0;

}

程序執(zhí)行結(jié)果:

總結(jié):

a、 類(lèi)模板 同樣也不是類(lèi),它僅在編譯時(shí)根據(jù)實(shí)例化本模板時(shí)傳遞的實(shí)參來(lái)生成具體的類(lèi)代碼!若 類(lèi)模板沒(méi)有被實(shí)例化也沒(méi)有被調(diào)用,那編譯器不會(huì)為本模板生成任何代碼也不對(duì)模板代碼作任何語(yǔ)法檢查。

3、  類(lèi)模板的特化

類(lèi)模板的特化又被叫做類(lèi)模板的定做,首先讓我們來(lái)了解下什么叫作定做。

通過(guò)上面幾個(gè)小節(jié)的學(xué)習(xí),我相信,大家都知道模板不能直接被使用:必須先給模板傳遞一個(gè)實(shí)參,將它實(shí)例化為一個(gè)模板類(lèi),然后才可以用它來(lái)定義具體的對(duì)象。這樣就隱含了一個(gè)問(wèn)題:

我們通過(guò)給模板傳遞一個(gè)實(shí)參來(lái)實(shí)例化的模板類(lèi)中的代碼都是在模板中定義好的,如果我們不能用與定義好的模板代碼來(lái)生成模板類(lèi),這時(shí)就需要使用模板的特化,也就是“定做”。

比如,我們剛才寫(xiě)好的雙向鏈表模板中,對(duì)于某一個(gè)類(lèi)(比如CStudent)來(lái)說(shuō),不允許添加重復(fù)的節(jié)點(diǎn),但是對(duì)于像普通的intdouble等數(shù)據(jù)類(lèi)型以及其它一些類(lèi)時(shí),又不需要有這類(lèi)的限制。這時(shí)我們就需要將此雙向鏈表模板針對(duì)這個(gè)不允許有重復(fù)節(jié)點(diǎn)的類(lèi)(如:CStudent)進(jìn)行特化,大致代碼如下:

template <>

class CDList<CStudent>

{

private:

int     m_nMessage; // 消息號(hào)

int     m_nCount; // 鏈表中 元素的數(shù)量

Node<CStudent>* m_pHead; // 鏈表頭指針

Node<CStudent>* m_pTail; // 鏈表尾指針

public:

bool Change(int nIndex1,int nIndex2);

void Release();

//增加

Node<CStudent>* AddTailCStudent Data );

Node<CStudent>* AddHeadCStudent Data );

Node<CStudent>* operator[](int nIndex);

//刪除

bool DeleteNodeint nIndex );

void PrintAll();

//查找

Node<CStudent>FindNodeint nIndex );

};

Node<CStudent>CDList<CStudent>::AddTail( CStudent Data )

{

Node<CStudent>* pNewNode = new Node<CStudent>(Data);

if ( m_pTail )

m_pTail->m_pNext = pNewNode;

pNewNode->m_pPrev = m_pTail;

if ( m_pTail == NULL )

m_pHead = pNewNode;

m_pTail = pNewNode;

m_nCount++;

return pNewNode;

}

由此可知,為CStudent類(lèi)定做的CDList模板類(lèi),就是以CDList<CStudent>為類(lèi)名重寫(xiě)一份CDList<CStudent>實(shí)現(xiàn)而拋棄編譯器為我們生成的CDList<CStudent>類(lèi)。

當(dāng)一個(gè)模板擁有多個(gè)模板參數(shù)時(shí),如果我們只對(duì)其部分參數(shù)定做則稱為“局部定做”,這樣定做出來(lái)的“物件”仍然是一個(gè)模板,因?yàn)槲覀冎惶鼗艘徊糠帜0鍏?shù).

說(shuō)明:

剛才,我們?yōu)?font face="Times New Roman">CStudent類(lèi)定做的CDList模板類(lèi),其實(shí)我們沒(méi)有必要將整個(gè)CDList<CStudent>類(lèi)都寫(xiě)一遍,只需要重寫(xiě)Add函數(shù)即可,例如:

Template<>

CDList<CStudent>::Add(CStudent& n)

{

……

}

當(dāng)然,這樣的代碼,需要寫(xiě)在Cpp文件中,并在.h文件中聲明。

三、 模板程序的組織

當(dāng)然,如果你足夠細(xì)心,你一定會(huì)好奇,為什么我給的例子中,模板的代碼都寫(xiě)在頭文件中(.h文件),這里我們就討論模板代碼的組織方式。C++支持兩種模板代碼的組織方式,分別是包含方式(我們使用的就是包含方式)和分離方式。這兩種組織方式?jīng)]有太根本的區(qū)別,就是一個(gè)將代碼全寫(xiě)在頭文件中,分離方式是像寫(xiě)類(lèi)一樣聲明和定義分別寫(xiě)在頭文件(.h文件)和實(shí)現(xiàn)文件(cpp文件)中。

下面我們分別討論下這兩種代碼組織方式。

1、  包含方式

本專(zhuān)題中,所有的實(shí)例代碼中的模板代碼都是以包含方式組織的。因?yàn)楹枚嗟木幾g器(如VC6cl)并不支持分離方式組織代碼,將代碼寫(xiě)在頭文件也只是方便編譯器的預(yù)處理工作能方便的將.h文件中的代碼根據(jù)模板實(shí)參的類(lèi)型生成相應(yīng)的模板類(lèi)。

當(dāng)然,將代碼都寫(xiě)在頭文件中還有一點(diǎn)點(diǎn)小要求:

A、 如果模板的成員函數(shù)寫(xiě)在類(lèi)外,則需要寫(xiě)成如下樣式(見(jiàn)Exp04):

template <typename T> // 每個(gè)類(lèi)外成員函數(shù)前都要有這句

Node<T>CDList<T>::AddTail( T Data )

{

Node<T>* pNewNode = new Node<T>(Data);

if ( m_pTail )

m_pTail->m_pNext = pNewNode;

pNewNode->m_pPrev = m_pTail;

if ( m_pTail == NULL )

m_pHead = pNewNode;

m_pTail = pNewNode;

m_nCount++;

return pNewNode;

}

B、 對(duì)于特化的代碼則需要在.h文件中聲明并在.cpp文件中定義,如果都寫(xiě)在.h文件中編譯會(huì)報(bào)重定義錯(cuò)誤。

2、  分離方式

上面已經(jīng)提到過(guò),所謂的分離方式組織代碼,就是將模板的聲明和定義分別寫(xiě)在頭文件(.h文件)和實(shí)現(xiàn)文件(cpp文件)中,需要注意的是,并不是所有的編譯器都支持這種寫(xiě)法,目前我只知道GCC支持這種寫(xiě)法。

當(dāng)然,分離方式組織代碼也有個(gè)小要求,就是在模板的聲明和定義的template關(guān)鍵字前都加上export關(guān)鍵字。比如:

// .h 頭文件中

export template <typename T>

class CDList

{

public:

CDList();

virtual ~CDList();

public:

bool Change(int nIndex1,int nIndex2);

void Release();

//增加

Node<T>* AddTail( T Data );

Node<T>* AddHead( T Data );

Node<T>* operator[](int nIndex);

//刪除

bool DeleteNode( int nIndex );

void PrintAll();

//查找

Node<T>* FindNode( int nIndex );

};

在實(shí)現(xiàn)文件(cpp文件)中。

export template <typename T> // 每個(gè)類(lèi)外成員函數(shù)前都要有這句

Node<T>CDList<T>::AddTail( T Data )

{

Node<T>* pNewNode = new Node<T>(Data);

if ( m_pTail )

m_pTail->m_pNext = pNewNode;

pNewNode->m_pPrev = m_pTail;

if ( m_pTail == NULL )

m_pHead = pNewNode;

m_pTail = pNewNode;

m_nCount++;

return pNewNode;

}

.

四、 學(xué)習(xí)小結(jié)

經(jīng)過(guò)上面各個(gè)小節(jié)的學(xué)習(xí),我相信大家一定像我一樣,對(duì)模板有了一點(diǎn)認(rèn)識(shí)。大家也一定都知道,模板只是在編譯期間編寫(xiě),所有的代碼都只有效與編譯期。

因此,模板的重載、特化等多態(tài)性也都是在編譯期間體現(xiàn)出來(lái)的,如果我們對(duì)編譯生成的可執(zhí)行文件進(jìn)行反匯編時(shí),我們不會(huì)找到任何與模板有關(guān)的代碼,因?yàn)槟0逯皇蔷幾g期間的產(chǎn)物。

關(guān)于模板的作用,我相信大家也一定都體會(huì)到了,它可以大大的減輕我們的編碼負(fù)擔(dān),提高編程效率。關(guān)于模板的用法和技巧還有很多,單單模板特性足可以出一本書(shū)的篇幅來(lái)描述其特性及用法。

因此本專(zhuān)題也只是帶領(lǐng)大家了解模板的基礎(chǔ)用法,關(guān)于模板的更多更深入知識(shí),請(qǐng)參考 “模板元編程”相關(guān)內(nèi)容。

Feedback

# re: 笨鳥(niǎo)先飛學(xué)編程系列之九-C++的模板編程  回復(fù)  更多評(píng)論   

2010-07-22 16:09 by 陳梓瀚(vczh)
學(xué)模板元編程之前,就算你沒(méi)學(xué)過(guò)haskell,你也應(yīng)該先學(xué)haskell再學(xué)模板元編程,加起來(lái)的時(shí)間比你直接學(xué)模板元編程要短。

# re: 笨鳥(niǎo)先飛學(xué)編程系列之九-C++的模板編程[未登錄](méi)  回復(fù)  更多評(píng)論   

2010-07-22 17:43 by besterChen
@陳梓瀚(vczh)
haskell?
這個(gè)我還真不知道,我這就去看看,(*^__^*) 嘻嘻……
謝謝vczh的指教~

# re: 笨鳥(niǎo)先飛學(xué)編程系列之九-C++的模板編程  回復(fù)  更多評(píng)論   

2010-07-22 22:38 by 空明流轉(zhuǎn)
@陳梓瀚(vczh)
其實(shí)沒(méi)必要。只要能理解“遞歸”和不動(dòng)點(diǎn)就可以了。
模板元編程最好不要看匯編,不是一個(gè)抽象層面的東西。

# re: 笨鳥(niǎo)先飛學(xué)編程系列之九-C++的模板編程  回復(fù)  更多評(píng)論   

2010-07-23 16:14 by yuegui2
1.2例子的返回值搞錯(cuò)了

template <typename T>
T* const& Max(T* const& a, T* const& b)
{
return *a < *b ? *b : *a;
}
返回值應(yīng)該是T吧
哈哈,小問(wèn)題...

# re: 笨鳥(niǎo)先飛學(xué)編程系列之九-C++的模板編程  回復(fù)  更多評(píng)論   

2010-07-23 18:32 by 陳梓瀚(vczh)
@空明流轉(zhuǎn)
因此用haskell理解這些東西比看著模板要容易得多,因?yàn)閔askell比模板元編程更加賞心悅目。

# re: 笨鳥(niǎo)先飛學(xué)編程系列之九-C++的模板編程[未登錄](méi)  回復(fù)  更多評(píng)論   

2010-07-23 19:02 by besterChen
@yuegui2
恩,謝謝提醒,我改過(guò)來(lái)~

# re: 笨鳥(niǎo)先飛學(xué)編程系列之九-C++的模板編程[未登錄](méi)  回復(fù)  更多評(píng)論   

2015-09-01 20:44 by 菜鳥(niǎo)
Windows編程基礎(chǔ)是本實(shí)用的好書(shū)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久视频国产精品免费视频在线| 中日韩视频在线观看| 日韩亚洲一区二区| 亚洲婷婷免费| 亚洲成色999久久网站| 亚洲精品裸体| 欧美a级一区| 午夜精品久久久久久久蜜桃app| 欧美一区二区三区视频| 91久久精品国产91久久性色tv| 亚洲美女视频网| 国产午夜精品理论片a级大结局 | 免费成人黄色av| 欧美另类视频在线| 久久国内精品自在自线400部| 亚洲午夜久久久久久久久电影院 | 久久―日本道色综合久久| 欧美大片91| 国产精品欧美一区二区三区奶水| 91久久黄色| 国产精品视频xxx| 欧美寡妇偷汉性猛交| 国产精品日韩久久久久| 亚洲成人直播| 国产亚洲一二三区| 亚洲人屁股眼子交8| 国语自产精品视频在线看一大j8 | 欧美日韩亚洲高清一区二区| 久久久久久久综合日本| 欧美精品久久久久久久久久| 久久久999国产| 国产精品亚洲а∨天堂免在线| 亚洲电影免费观看高清| 国产亚洲精品一区二555| 一区二区三区四区国产精品| 日韩视频一区二区三区在线播放免费观看 | 亚洲欧洲另类国产综合| 亚洲伊人观看| 亚洲一区二区成人在线观看| 欧美a级一区二区| 六月婷婷久久| 伊大人香蕉综合8在线视| 亚洲制服av| 午夜精品久久久久久久99黑人| 欧美激情bt| 欧美激情中文字幕乱码免费| 尤物网精品视频| 久久女同互慰一区二区三区| 久久视频免费观看| 精品999日本| 久久久欧美精品| 麻豆91精品| 亚洲国产精品99久久久久久久久| 久久精品91久久香蕉加勒比| 久久午夜电影| 激情伊人五月天久久综合| 久久久国产精品亚洲一区| 久久精品国产999大香线蕉| 国产丝袜美腿一区二区三区| 羞羞视频在线观看欧美| 开元免费观看欧美电视剧网站| 欧美日本亚洲视频| 日韩一级裸体免费视频| 亚洲一区二区三区中文字幕| 欧美日韩另类国产亚洲欧美一级| 亚洲激情啪啪| 亚洲精品少妇30p| 欧美成人亚洲| 亚洲精品免费网站| 欧美亚洲综合另类| 国内精品视频一区| 欧美成年人视频| 夜夜爽99久久国产综合精品女不卡| 在线亚洲欧美视频| 亚洲精品国产精品国产自| 欧美午夜宅男影院| 久久99在线观看| 久久国产主播精品| 欧美日韩亚洲一区二区三区四区 | 欧美日韩亚洲三区| 最新成人av网站| 亚洲在线观看视频网站| 国产精品美女久久久久久久| 亚洲欧美综合国产精品一区| 久久婷婷人人澡人人喊人人爽| 亚洲片在线资源| 国产精品福利网| 久久国产精品久久久久久久久久| 美女国内精品自产拍在线播放| 亚洲剧情一区二区| 美日韩精品免费| 欧美国产综合一区二区| 亚洲一区二区三| 国产尤物精品| 欧美不卡视频| 午夜精品偷拍| 亚洲国产欧美一区二区三区久久 | 亚洲成在人线av| 亚洲综合视频在线| 亚洲高清av| 国产精品白丝jk黑袜喷水| 久久先锋影音av| 亚洲一级二级| 欧美黄色日本| 欧美一区二区日韩一区二区| 亚洲剧情一区二区| 在线播放国产一区中文字幕剧情欧美 | 国产精品卡一卡二| 久久综合伊人77777| 亚洲午夜在线观看| 亚洲电影第三页| 久久久久九九九| 亚洲一区二区三区三| 亚洲电影激情视频网站| 国产精品一区在线观看| 欧美绝品在线观看成人午夜影视 | 亚洲制服av| 国产喷白浆一区二区三区| 欧美国产精品va在线观看| 久久av二区| 亚洲综合999| 一区二区三区久久久| 亚洲国产一区二区三区在线播| 久久精品国产久精国产爱| 亚洲永久精品大片| 在线视频欧美日韩| 亚洲国产经典视频| 黄色成人av网站| 国产日本欧美在线观看| 欧美性猛交99久久久久99按摩 | 一本久久精品一区二区| 欧美一区二区三区播放老司机| 亚洲毛片在线看| 久久精品主播| 久久免费少妇高潮久久精品99| 国产精品久久久久久久久免费樱桃| 久久精品一区二区三区不卡| 久久精品国产69国产精品亚洲| 亚洲视屏一区| 亚洲精品在线免费观看视频| 欧美激情精品久久久久久久变态| 可以免费看不卡的av网站| 久久野战av| 免费在线看一区| 你懂的成人av| 欧美激情一区二区三级高清视频| 亚洲一区在线视频| 亚洲精品五月天| 中文在线一区| 亚洲欧美在线免费| 久久国产高清| 久久亚洲综合色| 亚洲福利视频网站| 亚洲黄色一区二区三区| 亚洲日产国产精品| 中文在线一区| 欧美一区二区三区四区高清| 久久精品国产精品| 免费在线看成人av| 欧美日韩免费一区| 国产欧美欧美| 在线看日韩欧美| 亚洲毛片在线免费观看| 亚洲一区二区三区免费视频| 欧美中文字幕精品| 欧美a级片网站| 亚洲狼人综合| 小嫩嫩精品导航| 免费毛片一区二区三区久久久| 欧美成人嫩草网站| 国产精品久久久久久久久久久久 | 久久国产精品久久国产精品| 看欧美日韩国产| 日韩视频一区| 欧美在线观看一区二区| 欧美sm视频| 国产精品实拍| 亚洲黄色高清| 亚洲一区美女视频在线观看免费| 亚洲欧美国产精品va在线观看| 久久黄色网页| 亚洲人成77777在线观看网| 日韩系列在线| 欧美粗暴jizz性欧美20| 欧美日韩一区在线观看| 国产综合一区二区| 亚洲精品网站在线播放gif| 欧美有码在线观看视频| 欧美成人在线网站| 亚洲精品一区二区三区樱花| 欧美一区二区三区四区高清| 欧美精品在线观看| 狠狠色狠狠色综合| 亚洲午夜精品一区二区| 毛片基地黄久久久久久天堂 | 亚洲国产日韩欧美在线99| 亚洲欧美国产高清va在线播| 欧美国产日韩一二三区| 亚洲天堂男人| 欧美刺激性大交免费视频|