亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

c++中try catch的用法小結

2020-05-23 13:31:25
字體:
來源:轉載
供稿:網友

在c++中,可以直接拋出異常之后自己進行捕捉處理,如:(這樣就可以在任何自己得到不想要的結果的時候進行中斷,比如在進行數據庫事務操作的時候,如果某一個語句返回SQL_ERROR則直接拋出異常,在catch塊中進行事務回滾(回滾怎么理解?))。

#include <iostream> #include <exception> using namespace std; int main () {  try  {   throw 1;   throw "error";  }  catch(char *str)  {   cout << str << endl;  }  catch(int i)  {   cout << i << endl;  } }

也可以自己定義異常類來進行處理:

#include <iostream> #include <exception> using namespace std;  //可以自己定義Exception class myexception: public exception {  virtual const char* what() const throw()  {   return "My exception happened";  } }myex;  int main () {  try  {    if(true) //如果,則拋出異常;    throw myex;  }  catch (exception& e)  {   cout << e.what() << endl;  }  return 0; }

同時也可以使用標準異常類進行處理:

#include <iostream> #include <exception> using namespace std;  int main () {  try  {   int* myarray= new int[100000];  }  catch (exception& e)  {   cout << "Standard exception: " << e.what() << endl;  }  return 0; }

一、簡單的例子

首先通過一個簡單的例子來熟悉C++ 的 try/catch/throw(可根據單步調試來熟悉,try catch throw部分是如何運行的):

#include <stdlib.h>#include "iostream"using namespace std;double fuc(double x, double y)      //定義函數{ if(y==0) {  throw y;         //除數為0,拋出異常 } return x/y;         //否則返回兩個數的商}int _tmain(int argc, _TCHAR* argv[]){ double res; try           //定義異常 {  res=fuc(2,3);  cout<<"The result of x/y is : "<<res<<endl;  res=fuc(4,0);        //出現異常 } catch(double)         //捕獲并處理異常 {  cerr<<"error of dividing zero./n";  exit(1);         //異常退出程序 } return 0;}

catch 的數據類型需要與throw出來的數據類型相匹配的。

 

二、catch(...)的作用

  catch(…)能夠捕獲多種數據類型的異常對象,所以它提供給程序員一種對異常對象更好的控制手段,使開發的軟件系統有很好的可靠性。因此一個比較有經驗的程序員通常會這樣組織編寫它的代碼模塊,如下:

void Func(){  try  {    // 這里的程序代碼完成真正復雜的計算工作,這些代碼在執行過程中    // 有可能拋出DataType1、DataType2和DataType3類型的異常對象?!   catch(DataType1& d1)  {  }  catch(DataType2& d2)  {  }  catch(DataType3& d3)  {  }  /*********************************************************  注意上面try block中可能拋出的DataType1、DataType2和DataType3三  種類型的異常對象在前面都已經有對應的catch block來處理。但為什么  還要在最后再定義一個catch(…) block呢?這就是為了有更好的安全性和  可靠性,避免上面的try block拋出了其它未考慮到的異常對象時導致的程  序出現意外崩潰的嚴重后果,而且這在用VC開發的系統上更特別有效,因  為catch(…)能捕獲系統出現的異常,而系統異常往往令程序員頭痛了,現  在系統一般都比較復雜,而且由很多人共同開發,一不小心就會導致一個  指針變量指向了其它非法區域,結果意外災難不幸發生了。catch(…)為這種  潛在的隱患提供了一種有效的補救措施。  *********************************************************/  catch(…)  {  }}

三、異常中采用面向對象的處理

首先看下面的例子:

void OpenFile(string f){ try  {   // 打開文件的操作,可能拋出FileOpenException  }  catch(FileOpenException& fe)  {   // 處理這個異常,如果這個異??梢院芎玫牡靡曰謴?,那么處理完畢后函數   // 正常返回;否則必須重新拋出這個異常,以供上層的調用函數來能再次處    // 理這個異常對象   int result = ReOpenFile(f);   if (result == false) throw;  }}void ReadFile(File f){  try  {   // 從文件中讀數據,可能拋出FileReadException  }  catch(FileReadException& fe)  {   // 處理這個異常,如果這個異??梢院芎玫牡靡曰謴?,那么處理完畢后函數   // 正常返回;否則必須重新拋出這個異常,以供上層的調用函數來能再次處   // 理這個異常對象   int result = ReReadFile(f);   if (result == false) throw;  }}void WriteFile(File f){  try  {   // 往文件中寫數據,可能拋出FileWriteException  }  catch(FileWriteException& fe)  {   // 處理這個異常,如果這個異常可以很好的得以恢復,那么處理完畢后函數   // 正常返回;否則必須重新拋出這個異常,以供上層的調用函數來能再次處理這個異常對象    int result = ReWriteFile(f);   if (result == false) throw;   } }void Func(){  try  {   // 對文件進行操作,可能出現FileWriteException、FileWriteException   // 和FileWriteException異常   OpenFile(…);   ReadFile(…);   WriteFile(…);  }  // 注意:FileException是FileOpenException、FileReadException和FileWriteException  // 的基類,因此這里定義的catch(FileException& fe)能捕獲所有與文件操作失敗的異  // 常?! atch(FileException& fe)  {   ExceptionInfo* ef = fe.GetExceptionInfo();   cout << “操作文件時出現了不可恢復的錯誤,原因是:”<< fe << endl;  }}

下面是更多面向對象和異常處理結合的例子:

#include <iostream.h>class ExceptionClass{ char* name;public: ExceptionClass(const char* name="default name")  {    cout<<"Construct "<<name<<endl;    this->name=name; } ~ExceptionClass() {    cout<<"Destruct "<<name<<endl; } void mythrow() {   throw ExceptionClass("my throw"); }}void main(){  ExceptionClass e("Test");  try  {   e.mythrow();  }   catch(...)  {   cout<<”*********”<<endl;  }}

這是輸出信息:
Construct Test
Construct my throw
Destruct my throw
****************
Destruct my throw (這里是異常處理空間中對異常類的拷貝的析構)
Destruct Test
======================================

不過一般來說我們可能更習慣于把會產生異常的語句和要throw的異常類分成不同的類來寫,下面的代碼可以是我們更愿意書寫的:

class ExceptionClass{public: ExceptionClass(const char* name="Exception Default Class") {  cout<<"Exception Class Construct String"<<endl; } ~ExceptionClass() {  cout<<"Exception Class Destruct String"<<endl; } void ReportError() {  cout<<"Exception Class:: This is Report Error Message"<<endl; }};class ArguClass{ char* name;public: ArguClass(char* name="default name") {  cout<<"Construct String::"<<name<<endl;  this->name=name; } ~ArguClass() {  cout<<"Destruct String::"<<name<<endl; } void mythrow() {  throw ExceptionClass("my throw"); }  };_tmain(){ ArguClass e("haha"); try {  e.mythrow(); } catch(int) {  cout<<"If This is Message display screen, This is a Error!!"<<endl; //這行不會執行 } catch(ExceptionClass pTest) {  pTest.ReportError(); } catch(...) {  cout<<"***************"<<endl;  }}

輸出Message:
Construct String::haha
Exception Class Construct String
Exception Class Destruct String
Exception Class:: This is Report Error Message
Exception Class Destruct String
Destruct String::haha

四、構造和析構中的異常拋出

先看個程序,假如我在構造函數的地方拋出異常,這個類的析構會被調用嗎?可如果不調用,那類里的東西豈不是不能被釋放了?

#include <iostream.h>#include <stdlib.h>class ExceptionClass1{  char* s;public:  ExceptionClass1()  {    cout<<"ExceptionClass1()"<<endl;    s=new char[4];    cout<<"throw a exception"<<endl;    throw 18;  }  ~ExceptionClass1()  {    cout<<"~ExceptionClass1()"<<endl;    delete[] s;  }};void main(){  try  {    ExceptionClass1 e;  }  catch(...)  {}}

結果為:
ExceptionClass1()
throw a exception

在這兩句輸出之間,我們已經給S分配了內存,但內存沒有被釋放(因為它是在析構函數中釋放的)。應該說這符合實際現象,因為對象沒有完整構造。

為了避免這種情況,我想你也許會說:應避免對象通過本身的構造函數涉及到異常拋出。即:既不在構造函數中出現異常拋出,也不應在構造函數調用的一切東西中出現異常拋出。
但是在C++中可以在構造函數中拋出異常,經典的解決方案是使用STL的標準類auto_ptr。

那么,在析構函數中的情況呢?我們已經知道,異常拋出之后,就要調用本身的析構函數,如果這析構函數中還有異常拋出的話,則已存在的異常尚未被捕獲,會導致異常捕捉不到。

五、標準C++異常類

標準異常都派生自一個公共的基類exception?;惏匾亩鄳B性函數提供異常描述,可以被重載。下面是exception類的原型:

class exception{public: exception() throw(); exception(const exception& rhs) throw(); exception& operator=(const exception& rhs) throw(); virtual ~exception() throw(); virtual const char *what() const throw();}; C++有很多的標準異常類:namespace std{ //exception派生 class logic_error; //邏輯錯誤,在程序運行前可以檢測出來  //logic_error派生 class domain_error; //違反了前置條件 class invalid_argument; //指出函數的一個無效參數 class length_error; //指出有一個超過類型size_t的最大可表現值長度的對象的企圖 class out_of_range; //參數越界 class bad_cast; //在運行時類型識別中有一個無效的dynamic_cast表達式 class bad_typeid; //報告在表達試typeid(*p)中有一個空指針p  //exception派生 class runtime_error; //運行時錯誤,僅在程序運行中檢測到  //runtime_error派生 class range_error; //違反后置條件 class overflow_error; //報告一個算術溢出 class bad_alloc; //存儲分配錯誤}

標準庫異常類定義在以下四個頭文件中

1、exception頭文件:定義了最常見的標準異常類,其類名為exception。只通知異常的產生,但不會提供更多的信息

2、stdexcept頭文件定義了以下幾種常見異常類

函數   功能或作用

exception 最常見的問題

runtime_error 運行時錯誤:僅在運行時才能檢測到的問題

range_error 運行時錯誤:生成的結果超出了有意義的值域范圍

overflow_error 運行時錯誤:計算上溢

underflow_error 運行時錯誤:計算下溢

 

logic_error 邏輯錯誤:可在運行前檢測到的問題

domain_error 邏輯錯誤:參數的結果值不存在

invalid_argument 邏輯錯誤:不合適的參數

length_error 邏輯錯誤:試圖生成一個超出該類型最大長度的對象

out_of_range 邏輯錯誤:使用一個超出有效范圍的值

3、new頭文件定義了bad_alloc異常類型,提供因無法分配內存而由new拋出的異常

4、type_info頭文件定義了bad_cast異常類型(要使用type_info必須包含typeinfo頭文件)

下面是使用異常類的例子:

首先,我定義了幾個異常類,這些類也可以從標準異常類進行派生,如下

class BadInitializers{public: BadInitializers() {}};class OutOfBounds{public: OutOfBounds(int i) { cout<<"Size "<<i<<" is illegal!!!"<<endl; }};class SizeMismatch{public: SizeMismatch() {}};

然后要在程序中需要的地方使用throw來拋出異常類,兩個拋出異常類的例子如下

template <class T>Array1D<T>::Array1D(int sz){ if(sz<0) { //throw BadInitializers(); throw invalid_argument("Size has to be bigger than 0!!!"); } size=sz; element=new T[size];}template <class T>T &Array1D<T>::operator[](int i) const{ if(i<0||i>=size) { throw OutOfBounds(i); } return element[i];}

然后在主程序中使用try...catch...來捕獲異常,并進行相應的處理,如下

try{ int i=0; Array1D<int> a1(5); a1[0]=1; a1[1]=3; a1[2]=5; a1[3]=7; a1[4]=8; Array1D<int> a2(a1); for(i=0;i<a2.Size();i++) { cout<<a2[i]<<" "; } cout<<endl; Array1D<int> a3(5); a3=a1+a2; cout<<a3;} catch(BadInitializers) { cout<<"Error:BadInitializers!!!"<<endl; } catch(OutOfBounds &e) { cout<<"Error:OutOfBounds!!!"<<endl; } catch(SizeMismatch &e) { cout<<"Error:SizeMismatch!!!"<<endl; } catch(invalid_argument &e) { cout<<"Error:"<<e.what()<<endl; } catch(...) { cout<<"An unknown error!!!"<<endl; }

六、try finally使用

__try
{
file://保護塊
}
__finally
{
file://結束處理程序
}
在上面的代碼段中,操作系統和編譯程序共同來確保結束處理程序中的__f i n a l l y代碼塊能夠被執行,不管保護體(t r y塊)是如何退出的。不論你在保護體中使用r e t u r n,還是g o t o,或者是longjump,結束處理程序(f i n a l l y塊)都將被調用。

我們來看一個實列:(返回值:10, 沒有Leak,性能消耗:?。?/p>

DWORD Func_SEHTerminateHandle(){DWORD dwReturnData = 0;HANDLE hSem = NULL;const char* lpSemName = "TermSem";hSem = CreateSemaphore(NULL, 1, 1, lpSemName);__try{ WaitForSingleObject(hSem,INFINITE); dwReturnData = 5;}__finally{ ReleaseSemaphore(hSem,1,NULL); CloseHandle(hSem);}dwReturnData += 5;return dwReturnData;}

這段代碼應該只是做為一個基礎函數,我們將在后面修改它,來看看結束處理程序的作用:
====================
在代碼加一句:(返回值:5, 沒有Leak,性能消耗:中下)

DWORD Func_SEHTerminateHandle(){DWORD dwReturnData = 0;HANDLE hSem = NULL;const char* lpSemName = "TermSem";hSem = CreateSemaphore(NULL, 1, 1, lpSemName);__try{ WaitForSingleObject(hSem,INFINITE); dwReturnData = 5; return dwReturnData;}__finally{ ReleaseSemaphore(hSem,1,NULL); CloseHandle(hSem);}dwReturnData += 5;return dwReturnData;}

在try塊的末尾增加了一個return語句。這個return語句告訴編譯程序在這里要退出這個函數并返回dwTemp變量的內容,現在這個變量的值是5。但是,如果這個return語句被執行,該線程將不會釋放信標,其他線程也就不能再獲得對信標的控制。可以想象,這樣的執行次序會產生很大的問題,那些等待信標的線程可能永遠不會恢復執行。
  通過使用結束處理程序,可以避免return語句的過早執行。當return語句試圖退出try塊時,編譯程序要確保finally塊中的代碼首先被執行。要保證finally塊中的代碼在try塊中的return語句退出之前執行。在程序中,將ReleaseSemaphore的調用放在結束處理程序塊中,保證信標總會被釋放。這樣就不會造成一個線程一直占有信標,否則將意味著所有其他等待信標的線程永遠不會被分配CPU時間。
  在finally塊中的代碼執行之后,函數實際上就返回。任何出現在finally塊之下的代碼將不再執行,因為函數已在try塊中返回。所以這個函數的返回值是5,而不是10。
  讀者可能要問編譯程序是如何保證在try塊可以退出之前執行finally塊的。當編譯程序檢查源代碼時,它看到在try塊中有return語句。這樣,編譯程序就生成代碼將返回值(本例中是5)保存在一個編譯程序建立的臨時變量中。編譯程序然后再生成代碼來執行f i n a l l y塊中包含的指令,這稱為局部展開。更特殊的情況是,由于try塊中存在過早退出的代碼,從而產生局部展開,導致系統執行finally塊中的內容。在finally塊中的指令執行之后,編譯程序臨時變量的值被取出并從函數中返回。
  可以看到,要完成這些事情,編譯程序必須生成附加的代碼,系統要執行額外的工作。

finally塊的總結性說明

我們已經明確區分了強制執行finally塊的兩種情況:
• 從try塊進入finally塊的正??刂屏?。
• 局部展開:從try塊的過早退出(goto、long jump、continue、break、return等)強制控制轉移到finally塊。
第三種情況,全局展開( global unwind),這個以后再看。

 

七、C++異常參數傳遞

從語法上看,在函數里聲明參數與在catch子句中聲明參數是一樣的,catch里的參數可以是值類型,引用類型,指針類型。例如:

try{ .....}catch(A a){}catch(B& b){}catch(C* c){}

盡管表面是它們是一樣的,但是編譯器對二者的處理卻又很大的不同。調用函數時,程序的控制權最終還會返回到函數的調用處,但是拋出一個異常時,控制權永遠不會回到拋出異常的地方。

class A;void func_throw(){  A a;  throw a; //拋出的是a的拷貝,拷貝到一個臨時對象里}try{ func_throw();}catch(A a) //臨時對象的拷貝{}

當我們拋出一個異常對象時,拋出的是這個異常對象的拷貝。當異常對象被拷貝時,拷貝操作是由對象的拷貝構造函數完成的。該拷貝構造函數是對象的靜態類型(static type)所對應類的拷貝構造函數,而不是對象的動態類型(dynamic type)對應類的拷貝構造函數。此時對象會丟失RTTI信息。

  異常是其它對象的拷貝,這個事實影響到你如何在catch塊中再拋出一個異常。比如下面這兩個catch塊,乍一看好像一樣:

catch (A& w) // 捕獲異常{ // 處理異?!hrow; // 重新拋出異常,讓它繼續傳遞}catch (A& w) // 捕獲Widget異常{ // 處理異?!hrow w; // 傳遞被捕獲異常的拷貝}

第一個塊中重新拋出的是當前異常(current exception),無論它是什么類型。(有可能是A的派生類)  
  第二個catch塊重新拋出的是新異常,失去了原來的類型信息。
  一般來說,你應該用throw來重新拋出當前的異常,因為這樣不會改變被傳遞出去的異常類型,而且更有效率,因為不用生成一個新拷貝。
看看以下這三種聲明:
catch (A w) ... // 通過傳值
catch (A& w) ... // 通過傳遞引用,一個被異常拋出的對象(總是一個臨時對象)可以通過普通的引用捕獲
catch (const A& w) ... //const引用

catch (A w) ... // 通過傳值捕獲
會建立兩個被拋出對象的拷貝,一個是所有異常都必須建立的臨時對象,第二個是把臨時對象拷貝進w中。實際上,編譯器會優化掉一個拷貝。
同樣,當我們通過引用捕獲異常時,
catch (A& w) ... // 通過引用捕獲
catch (const A& w) ... //const引用捕獲
這仍舊會建立一個被拋出對象的拷貝:拷貝是一個臨時對象。相反當我們通過引用傳遞函數參數時,沒有進行對象拷貝。話雖如此,但是不是所有編譯器都如此。 

通過指針拋出異常與通過指針傳遞參數是相同的。不論哪種方法都是一個指針的拷貝被傳遞。你不能認為拋出的指針是一個指向局部對象的指針,因為當異常離開局部變量的生存空間時,該局部變量已經被釋放。Catch子句將獲得一個指向已經不存在的對象的指針。這種行為在設計時應該予以避免。
  另外一個重要的差異是在函數調用者或拋出異常者與被調用者或異常捕獲者之間的類型匹配的過程不同。在函數傳遞參數時,如果參數不匹配,那么編譯器會嘗試一個類型轉換,如果存在的話。而對于異常處理的話,則完全不是這樣。見一下的例子:

void func_throw(){  CString a;  throw a; //拋出的是a的拷貝,拷貝到一個臨時對象里}try{func_throw();}catch(const char* s){}

  盡管如此,在catch子句中進行異常匹配時可以進行兩種類型轉換。第一種是基類與派生類的轉換,一個用來捕獲基類的catch子句也可以處理派生類類型的異常。反過來,用來捕獲派生類的無法捕獲基類的異常
  第二種是允許從一個類型化指針(typed pointer)轉變成無類型指針(untyped pointer),所以帶有const void* 指針的catch子句能捕獲任何類型的指針類型異常:
catch (const void*) ... //可以捕獲所有指針異常
  另外,你還可以用catch(...)來捕獲所有異常,注意是三個點。
  傳遞參數和傳遞異常間最后一點差別是catch子句匹配順序總是取決于它們在程序中出現的順序。因此一個派生類異常可能被處理其基類異常的catch子句捕獲,這叫異常截獲,一般的編譯器會有警告。

class A {public:A(){cout << "class A creates" << endl;}void print(){cout << "A" << endl;}~A(){cout << "class A destruct" << endl;}};class B: public A{public:B(){cout << "class B create" << endl;}void print(){cout << "B" << endl;}~B(){cout << "class B destruct" << endl;}};void func(){ B b; throw b;}try{ func();}catch( B& b) //必須將B放前面,如果把A放前面,B放后面,那么B類型的異常會先被截獲。{ b.print();}catch (A& a){ a.print() ;}

這篇文章就介紹到這了,需要的朋友可以參考一下。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
热久久这里只有| 国产ts人妖一区二区三区| 91精品啪aⅴ在线观看国产| 欲色天天网综合久久| 日韩电影中文 亚洲精品乱码| 国产成人综合精品| 97成人超碰免| 色噜噜久久综合伊人一本| 欧美高清电影在线看| 欧美理论片在线观看| 亚洲欧美日韩精品久久奇米色影视| 久久99精品久久久久久琪琪| 日韩电影免费观看中文字幕| www.欧美免费| 国产成人久久久| 亚洲精品国产成人| 亚洲第一黄色网| 日本成熟性欧美| 欧美视频专区一二在线观看| 国产成人精品久久| 欧美激情精品久久久久久免费印度| 秋霞午夜一区二区| 欧美精品aaa| 欧美天天综合色影久久精品| 亚洲全黄一级网站| 亚洲天堂成人在线视频| 日本久久91av| 日韩中文字幕免费看| 国产精品久在线观看| 国产精品麻豆va在线播放| 成人深夜直播免费观看| 久久久999精品视频| 国产一区二区在线免费| 欧美成人午夜激情视频| 久久成人亚洲精品| 成人国产精品av| 日韩欧美在线网址| 国产日韩中文字幕| 神马久久桃色视频| 欧美乱妇高清无乱码| 亚洲第一福利视频| 日韩美女毛茸茸| 欧美精品久久久久久久| 国产成人a亚洲精品| 91在线观看免费网站| 日韩国产在线播放| 色777狠狠综合秋免鲁丝| 国产成人精品亚洲精品| 国产精品综合不卡av| 久久视频精品在线| 欧美黄色小视频| 欧美乱大交xxxxx另类电影| 国产一区二区三区丝袜| 久久精品久久久久电影| 亚洲国产精品va在线看黑人| 亚洲国产成人精品一区二区| 欧美精品videos| 中文字幕亚洲欧美日韩2019| 8x拔播拔播x8国产精品| 8x拔播拔播x8国产精品| 成人高清视频观看www| 欧美激情在线观看视频| 日韩视频一区在线| 精品中文视频在线| 91精品免费看| 亚洲国产精品中文| 久久久久国色av免费观看性色| 欧美激情精品久久久久久久变态| 欧美性生活大片免费观看网址| 亚洲乱码一区av黑人高潮| 精品美女永久免费视频| 国产日产久久高清欧美一区| 国产视频综合在线| 国产精品福利在线观看网址| 欧美激情免费视频| 欧美日韩成人在线播放| 国产精品久久999| 国产精品高潮呻吟久久av黑人| 亚洲国产一区二区三区四区| 久久久久久久一| 国产精品黄页免费高清在线观看| 8090成年在线看片午夜| 俺去亚洲欧洲欧美日韩| 国产日韩欧美另类| 日韩在线观看av| 久久国产精品99国产精| 2019亚洲男人天堂| 久久久久久久久电影| 成人国内精品久久久久一区| 国产福利成人在线| 久久国内精品一国内精品| 尤物精品国产第一福利三区| 成人欧美一区二区三区黑人| 国产一区二区三区直播精品电影| 久久亚洲电影天堂| 欧美成人午夜激情| 国产99久久精品一区二区 夜夜躁日日躁| 精品中文视频在线| 综合网日日天干夜夜久久| 亚洲久久久久久久久久久| 久久久中精品2020中文| 最近日韩中文字幕中文| 亚洲国产成人在线视频| 国产精品激情自拍| 亚洲国产97在线精品一区| 国产精品狼人色视频一区| 欧美激情一级二级| 国产欧美一区二区三区久久| 国产中文欧美精品| 中文字幕在线亚洲| 精品亚洲永久免费精品| 国产999精品视频| 亚洲图片在区色| 亚洲毛片在线免费观看| 亚洲男人天堂2024| 国产精品免费看久久久香蕉| 久久亚洲精品网站| 亚洲第一福利网| 国产日韩在线视频| 一区二区欧美久久| 欧美大荫蒂xxx| 最好看的2019的中文字幕视频| 亚洲精品小视频在线观看| 日本成人激情视频| 欧美日韩免费一区| 国产精品草莓在线免费观看| 国产精品日本精品| 亚洲日本成人女熟在线观看| 欧美在线免费视频| 欧美区二区三区| 秋霞成人午夜鲁丝一区二区三区| 亚洲日本aⅴ片在线观看香蕉| 黑人狂躁日本妞一区二区三区| 久久夜精品va视频免费观看| 久久久99免费视频| 91av在线影院| 亚洲电影中文字幕| 91在线视频导航| 国产精自产拍久久久久久蜜| 精品久久久在线观看| 欧美二区在线播放| 欧美亚洲伦理www| 亚洲成人av在线播放| 91久久中文字幕| 一区二区三区视频观看| 国语对白做受69| 欧美极品在线视频| 亚洲国产精品久久| 精品亚洲一区二区三区四区五区| 国产精品美乳一区二区免费| 亚洲欧美中文日韩在线| 久久精品最新地址| 久久视频免费在线播放| 精品久久久国产| 日韩高清电影免费观看完整版| 成人黄色免费看| 中文字幕日韩欧美| 亚洲a一级视频| 九九热99久久久国产盗摄| 国产在线精品播放| 亚洲女人天堂av| 日韩成人在线电影网| 欧美福利视频在线观看| 日本久久中文字幕|