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

C++程序設計建立對象間消息連接(附程序清單)

開發 后端
標識對象間的關系或建立對象間的消息連接是面向對象程序設計的一項重要任務。本文著重從C++程序設計的角度,提出一種建立對象間消息連接的實用方法,給各位讀者提供C++學習的參考。

  用過C++進行過面向對象程序設計的用戶都知道,程序中的對象很少單獨存在。不考慮對象間的相互作用幾乎是不可能的。所以,標識對象間的關系或建立對象間的消息連接是面向對象程序設計的一項重要任務。本文著重從C++程序設計的角度,提出一種建立對象間消息連接的實用方法。如果你想詳細了解面向對象程序設計技術,請參閱有關專著。

  大家都知道對象是數據和方法的封裝體。在C++中,它們分別表現為數據成員和成員函數。程序設計者通過執行對象的各種方法,來改變對象的狀態(即改變對象的屬性數據)。從而使該對象發生某些“事件”。當一對象發生某事件時,它通常需向其它相關對象發送“消息”,請求它們作出一些處理。 這時,發生事件并向其它對象請求處理的對象被稱為“事件對象”,而處理事件的對象被稱為“回調對象”。回調對象對事件的處理稱為“回調函數”。在C++中,這一過程相當于:當事件對象發生事件時,調用回調對象的某些成員函數。通常的作法是回調對象向事件對象傳遞對象指針。但這種方法不通用。為了減少程序設計的工作量,本文提出一種建立對象間消息連接的系統方法。它的思路是:將“事件發生→請求處理→執行處理”這一過程抽象成一個“回調”(CallBack)類。通過繼承,用戶可以輕松獲取建立對象間消息連接的機制。

  一、回調類的數據結構及其成員函數

  本文提出的CallBack類支持三種回調函數。它們是:回調對象中的成員函數,屬于回調類的靜態成員函數和普通的C函數。CallBackle類中包含一回調函數表callBackList。它用于記錄事件名稱,指向回調函數及回調對象的指針。該表的每一個節點為一個事件記錄EventRecord。每個事件記錄包含三個域:事件名指針eventName,指向回調對象的指針pointerToCBO,指向回調函數的指針pointerToCBF或pointerToCBSF(其中,pointerToCBF指向回調對象的成員函數,pointerToCBSF指向回調類的靜態成員函數或普通函數。它們同處于一共用體內)。CallBack類所提供的回調機制是這樣的:在事件對象上注冊回調對象中的回調函數;當事件發生時,事件對象在其回調表中檢索并執行回調函數。從而使二者的消息連接得以建立。(關于該類的具體實現,請參閱文后所附的程序清單)

事件名 回調對象指針 回調函數指針
“event” pointerCBO pointerToCBF或pointerTOCBSF

  AddCallBack: 注冊事件名和指向回調函數,回調對象的指針

  CallCallBack: 在回調表中,檢索注冊在指定事件上回調函數并調用它們

  事件發生時,調用CallCallBack函數

  對事件event進行處理的成員函數

  從CallBack類繼承的回調表callBackList, 成員函數AddCallBack和CallCallBack。

  當回調函數為靜態成員函數或普通C函數時, pointerToCBO為NULL。

  事件名是回調表callBackLis中的檢索關鍵字。

  回調對象中其它成員函數

  CallBack類的成員函數AddCallBack用來將回調函數注冊到事件對象的回調表中。它有兩個重載版本:

  1. void CallBack::AddCallBack(char *event,CallBackFunction cbf,CallBack *p);   
  2. void CallBack::AddCallBack(char *event,CallBackStaticFunction cbsf); 

  其中,***個AddCallBack用來將某回調對象的成員函數注冊到事件對象的回調表中。第二個AddCallBack用來將或某回調類的靜態成員函數注冊到事件對象的回調表中。在上參數表中,event是指向事件名字符串的指針,p是指向回調對象的指針,cbf和cbsf分別是指向成員函數及靜態成員函數(或普通函數)的指針。當回調函數來自某回調對象SomeObject時,傳遞成員函數指針應采用如下格式:(CallBackFunction)&SomeObject::MemberFunctionName; 傳遞SomeObject類的某靜態成員函數指針應采用格式:(CallBackStaticFunction)& SomeObject::FunctionName;傳遞程序中普通函數指針時,只需傳遞函數名即可。

  CallBack類的成員函數void CallBack::CallCallBack(char *ename, CallData calldata = NULL)用來調用注冊在事件ename上的所有回調函數。其中,calldata為數據指針(CallData實際上就是void*,詳見程序清單)。事件對象可通過它向回調對象傳遞有用的數據。該成員函數通常在事件對象的成員函數中調用,因為通常只有事件對象的成員函數才能改變對象的內部數據,從而使某些事件發生。

  成員函數RemoveCallback用來刪除注冊在事件對象上的回調函數。它的三個重載版本依次為:

  1. void CallBack::RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p);   
  2. void CallBack::RemoveCallBack(char *event,CallBackStaticFunction cbsf);   
  3. void CallBack::RemoveCallBack(char *event); 

  其中,event,cbf,cbsf,p等參數和成員函數AddCallBack中各參數一樣。***個RemoveCallBack用于刪除注冊在事件event上某回調對象的一個成員函數。第二個RemoveCallBack用于刪除注冊在事件event上的某普通函數或某回調類的一個靜態成員函數。第三個RemoveCallBack用于刪除注冊在事件event上的全部回調函數。

#p#

  二、CallBack類的使用方法

  使用CallBack類,可按以下步驟進行:

  1.確定程序中哪些對象間存在關系,需要建立消息連接。并確定在各特定消息連接關系中,哪個對象是事件對象,哪個對象是回調對象。

  2.事件對象類和回調對象類都必須從CallBack類繼承,以獲得回調支持。

  3.為事件對象注冊回調數據。包括:事件名,回調函數名,指向回調對象的指針。

  4.當你感興趣的事件發生時,在事件對象類引發事件的成員函數中調用CallCallBack函數。

  下面是一個具體的例子。通過它你會對Callback類的使用方法有進一步的了解。

  1. //測試程序文件:test.cpp    
  2. #include"callback.h"   
  3. //“揚聲器”類    
  4. class Speaker:public CallBack   
  5. {   
  6. private:  
  7.  int volume;  
  8. public:  
  9.  Speaker(int v): volume(v) {}  
  10. void IncreaseVolume(int v) //增加音量成員函數  
  11.  {  
  12.   volume += v;  
  13.   if(volume > 20){ //“音量大于20”事件發生了  
  14.    //調用注冊在兩事件上的回調函數  
  15.    CallCallBack("音量改變了");  
  16.    CallCallBack("音量大于20", &volume);  
  17.  }  
  18. }   
  19. void DecreaseVolume(int v) //降低音量成員函數   
  20. {  
  21.  volume -= v;  
  22.  if(volume < 5){ //“音量小于5”事件發生了  
  23.  //調用注冊在兩事件上的回調函數  
  24.   CallCallBack("音量改變了");  
  25.   CallCallBack("音量小于5", &volume);  
  26. }   
  27. }   
  28. };   
  29. //“耳朵”類    
  30. class Ear : public CallBack   
  31. {  
  32.  public:  
  33.   static void Response(CallData callData) //對“音量改變”的反應  
  34.   {  
  35.    cout<<"音量改變了."<<endl;  
  36.   }   
  37. void HighVoiceResponse(CallData callData)//對高音的反應   
  38. {  
  39.  cout<<”喂!太吵了!現在音量是:"<<*((int *)callData)<<endl;  
  40. }   
  41. void LowVoiceResponse(CallData callData)// 對低音的反應   
  42. {  
  43.  cout<<"啊!我聽不清了。現在音量是:"<<*((int *)callData)<<endl;  
  44. }   
  45. };   
  46. void main(void)    
  47. {  
  48. Speaker s(10); //現在音量為10  
  49. Ear e;   
  50. //為事件對象s注冊回調函數  
  51. s.AddCallBack("音量大于20”,(CallBackFunction)&Ear::HighVoiceResponse,&e);  
  52. s.AddCallBack("音量小于5”,(CallBackFunction)&Ear::LowVoiceResponse,&e);  
  53. s.AddCallBack("音量改變了",(CallBackStaticFunction)&Ear::Response);  
  54. s.IncreaseVolume(12);//將音量增加12,現在音量位22  
  55. s.DecreaseVolume(20);//將音量減少20,現在音量位2   

  運行結果:

  音量改變了.

  喂!太吵了!現在音量是:22

  音量改變了.

  啊!我聽不清了。現在音量是:2

  在上例中,揚聲器對象s為事件對象,耳朵對象e為回調對象。。s上被注冊了三個事件:“音量改變了”,“音量大于20”,“音量小于5”。 回調函數分別為:Ear::Response, Ear::HighVoiceResponse,Ear::LowVoiceResponse。當揚聲器s通過其成員函數IncreaseVolume和 DecreaseVolume改變音量時,回調對象e會自動作出反應。可見,通過使用CallBack類,在對象間建立消息連接已變為一項很簡單和優美的工作。

#p#

  附:程序清單(本程序在MS VC++5.0和TC++3.0上均編譯通過)

  1. //回調類的類結構:callback.h   
  2. #ifndef _CALLBACK_H   
  3. #define _CALLBACK_H   
  4. #include<stdlib.h>   
  5. #include<string.h>   
  6. #include<iostream.h> 
  7. #define CALLBACKLIST_INIT_SIZE 10   
  8. #define CALLBACKLIST_INCREMENT 5   
  9. class CallBack;   
  10. typedef void *CallData;//回調數據指針類型定義   
  11. typedef void (CallBack::*CallBackFunction)(CallData); //指向回調成員函數的指針   
  12. typedef void (*CallBackStaticFunction)(CallData); //指向靜態成員函數或普通函數的指針類型定義   
  13. class EventRecord{    
  14. private:   
  15. char *eventName; //回調事件名稱   
  16. CallBack *pointerToCBO;//指向回調對象的指針   
  17. //指向成員函數的指針和指向靜態成員函數(或普通函數)指針的共用體   
  18. union{   
  19. CallBackFunction pointerToCBF;   
  20. CallBackStaticFunction pointerToCBSF;   
  21. };   
  22. public:   
  23. EventRecord(void); //事件記錄類的缺省構造函數   
  24. //構造包含成員函數的事件記錄   
  25. EventRecord(char *ename,CallBack *pCBO,CallBackFunction pCBF);   
  26. //構造包含靜態成員函數或普通函數的事件記錄   
  27. EventRecord(char *ename,CallBackStaticFunction pCBSF);   
  28. ~EventRecord(void);//析構事件記錄   
  29. void operator = (const EventRecord& er);//重載賦值運算符   
  30. //判斷當前事件記錄的事件名是否為ename   
  31. int operator == (char *ename) const;   
  32. //判斷當前事件記錄是否和指定事件記錄相等   
  33. int operator == (const EventRecord& er) const;   
  34. void Flush(void); //將當前事件記錄清空   
  35. int IsEmpty(voidconst;//判斷事件記錄是否為空(即事件名是否為空)   
  36. friend class CallBack; //讓CallBack類能訪問EventRecord的私有成員;   
  37. };   
  38. class CallBack {    
  39. private:   
  40. EventRecord *callBackList; //回調事件表   
  41. int curpos; //當前事件記錄位置   
  42. int lastpos; //回調表中***一空閑位置   
  43. int size; //回調表的大小   
  44. void MoveFirst(void) { curpos = 0; }//將當前記錄置為***條記錄   
  45. void MoveNext(void//將下一條記錄置為當前記錄   
  46. {   
  47. if(curpos == lastpos) return;   
  48. curpos++;   
  49. }   
  50. //判斷回調表是否被遍歷完    
  51. int EndOfList(voidconst { return curpos == lastpos; }   
  52. public:   
  53. CallBack(void);//構造函數   
  54. CallBack(const CallBack& cb);//拷貝構造函數   
  55. ~CallBack(void);//析構函數   
  56. void operator = (const CallBack& cb);// 重載賦值運算符   
  57. //將回調對象的成員函數、靜態成員函數(或普通函數)   
  58. //注冊為事件對象的回調函數   
  59. void AddCallBack(char *event,CallBackFunction cbf,CallBack *p);   
  60. void AddCallBack(char *event,CallBackStaticFunction cbsf);   
  61. //刪除注冊在指定事件上的回調函數   
  62. void RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p);   
  63. void RemoveCallBack(char *event,CallBackStaticFunction cbsf);   
  64. void RemoveCallBack(char *event);// 刪除某事件的全部記錄   
  65. //執行注冊在某一事件上的所有回調函數   
  66. void CallCallBack(char *event, CallData calldata = NULL);   
  67. };   
  68. #endif   
  69. //回調類的實現:callback.cpp    
  70. #include"callback.h"   
  71.  //EventRecord類的實現   
  72. EventRecord::EventRecord(void)   
  73. {   
  74. eventName = NULL;   
  75. pointerToCBO = NULL;   
  76. //因為sizeof(CallBackFunction) > sizeof(CallBackStaticFunction)   
  77. pointerToCBF = NULL;   
  78. }   
  79. EventRecord::EventRecord(char *ename, CallBack *pCBO, CallBackFunction pCBF)   
  80. :pointerToCBO(pCBO), pointerToCBF(pCBF)   
  81. {   
  82. eventName = strdup(ename);   
  83. }   
  84. EventRecord::EventRecord(char *ename, CallBackStaticFunction pCBSF)   
  85. :pointerToCBO(NULL), pointerToCBSF(pCBSF)   
  86. {   
  87. eventName = strdup(ename);   
  88. }   
  89. EventRecord::~EventRecord(void)    
  90. {   
  91. if(eventName) delete eventName;   
  92. }   
  93. void EventRecord::operator = (const EventRecord& er)    
  94. {   
  95. if(er.eventName)   
  96. eventName = strdup(er.eventName);   
  97. else  
  98. eventName = NULL;   
  99. pointerToCBO = er.pointerToCBO;   
  100. pointerToCBF = er.pointerToCBF;   
  101. }   
  102. int EventRecord::operator == (char *ename) const    
  103. {   
  104. if((eventName == NULL)||ename == NULL)   
  105. return eventName == ename;   
  106. else  
  107. return strcmp(eventName,ename) == 0;   
  108. }   
  109. int EventRecord::operator == (const EventRecord& er) const  
  110. {   
  111. return (er == eventName) /*er和eventname不能交換位置*/  
  112. &&(pointerToCBO == er.pointerToCBO)   
  113. &&(pointerToCBO ?   
  114. (pointerToCBF == er.pointerToCBF):   
  115. (pointerToCBSF == er.pointerToCBSF));   
  116. }   
  117. void EventRecord::Flush(void)    
  118. {   
  119. if(eventName){   
  120. delete eventName;  
  121. eventName = NULL;  
  122. }   
  123. pointerToCBO = NULL;   
  124. pointerToCBF = NULL;   
  125. }   
  126. int EventRecord::IsEmpty(voidconst  
  127. {   
  128. if(eventName == NULL)   
  129. return 1;   
  130. else  
  131. return 0;   
  132. }   
  133. //Callback類的實現    
  134. CallBack::CallBack(void)   
  135. {   
  136. //按初始尺寸為回調表分配內存空間   
  137. callBackList = new EventRecord[CALLBACKLIST_INIT_SIZE];   
  138. if(!callBackList){   
  139. cerr<<"CallBack: memory allocation error."<<endl;   
  140. exit(1);   
  141. }   
  142. size = CALLBACKLIST_INIT_SIZE;   
  143. lastpos = 0;   
  144. curpos = 0;   
  145. }   
  146. CallBack::CallBack(const CallBack& cb): curpos(cb.curpos),lastpos(cb.lastpos),size(cb.size)    
  147. {   
  148. callBackList = new EventRecord[size];   
  149. if(!callBackList){   
  150. cerr<<"CallBack: memory allocation error."<<endl;   
  151. exit(1);   
  152. }   
  153. //一一復制各條事件記錄   
  154. for(int i = 0; i < size; i++) callBackList[i] = cb.callBackList[i];   
  155. }   
  156. void CallBack::operator = (const CallBack& cb)    
  157. {   
  158. curpos = cb.curpos;   
  159. lastpos = cb.lastpos;   
  160. size = cb.size;   
  161. delete [] callBackList;//刪除舊的回調表   
  162. callBackList = new EventRecord[size];//重新分配內存空間   
  163. if(!callBackList){   
  164. cerr<<"CallBack: memory allocation error."<<endl;   
  165. exit(1);   
  166. }   
  167. //一一復制各條事件記錄   
  168. for(int i = 0; i < size; i++) callBackList[i] = cb.callBackList[i];   
  169. }   
  170. CallBack::~CallBack(void)    
  171. {   
  172. delete [] callBackList;   
  173. }   
  174. void CallBack::AddCallBack(char *event, CallBackFunction pCBF, CallBack *pCBO)    
  175. {   
  176. //如事件名為空,退出   
  177. if( (event == NULL)?1:(strlen(event) == 0)) return;   
  178. //尋找因刪除事件記錄而產生的***個空閑位置,并填寫新事件記錄   
  179. for(int start=0;start<lastpos;start++)   
  180. if(callBackList[start].IsEmpty()){   
  181. callBackList[start] = EventRecord(event,pCBO,pCBF);   
  182. break;   
  183. }   
  184. if(start < lastpos) return//確實存在空閑位置   
  185. //沒有空閑位置,在回調表后追加新記錄   
  186. if(lastpos == size) //回調表已滿,需“伸長”   
  187. {   
  188. EventRecord *tempList = callBackList;//暫存舊回調表指針   
  189. //以一定的步長“伸長”回調表   
  190. callBackList = new EventRecord[size + CALLBACKLIST_INCREMENT];   
  191. if(!callBackList){   
  192. cerr<<"CallBack: memory allocation error."<<endl;   
  193. exit(1);   
  194. }   
  195. //復制舊回調表中的記錄   
  196. for(int i = 0; i < size; i++) callBackList[i] = tempList[i];   
  197. delete [] tempList;//刪除舊回調表   
  198. size += CALLBACKLIST_INCREMENT;//記下新回調表的尺寸   
  199. }   
  200. //構造新的事件記錄并將其填入回調表中   
  201. callBackList[lastpos] = EventRecord(event,pCBO,pCBF);   
  202. lastpos++;   
  203. }   
  204. void CallBack::AddCallBack(char *event,CallBackStaticFunction pCBSF)    
  205. {   
  206. if( (event == NULL)?1:(strlen(event) == 0)) return;   
  207. for(int start=0;start<lastpos;start++)   
  208. if(callBackList[start].IsEmpty()){   
  209. callBackList[start] = EventRecord(event,pCBSF);   
  210. break;   
  211. }   
  212. if(start < lastpos) return//a hole is found   
  213. if(lastpos == size) //event list is insufficient   
  214. {   
  215. EventRecord *tempList = callBackList;   
  216. callBackList = new EventRecord[size + CALLBACKLIST_INCREMENT];    
  217. if(!callBackList){   
  218. cerr<<"CallBack: memory allocation error."<<endl;   
  219. exit(1);   
  220. }   
  221. for(int i = 0; i < size; i++) callBackList[i] = tempList[i];   
  222. delete [] tempList;   
  223. size += CALLBACKLIST_INCREMENT;   
  224. }   
  225. callBackList[lastpos] = EventRecord(event,pCBSF);   
  226. lastpos++;   
  227. }   
  228. //刪除注冊在指定事件上的成員函數   
  229. void CallBack::RemoveCallBack(char *event, CallBackFunction pCBF, CallBack *pCBO)   
  230. {   
  231. if( (event == NULL)?1:(strlen(event) == 0)) return;   
  232. EventRecord er(event,pCBO,pCBF);   
  233. for(int i = 0; i < lastpos; i++)   
  234. if(callBackList[i] == er) callBackList[i].Flush();   
  235. }   
  236. //刪除注冊在指定事件上的靜態成員函數或普通函數   
  237. void CallBack::RemoveCallBack(char *event,CallBackStaticFunction pCBSF)   
  238. {   
  239. if( (event == NULL)?1:(strlen(event) == 0)) return;   
  240. EventRecord er(event,pCBSF);    
  241. for(int i = 0; i < lastpos; i++)   
  242. if(callBackList[i] == er) callBackList[i].Flush();   
  243. }   
  244. //刪除注冊在指定事件上的所有回調函數   
  245. void CallBack::RemoveCallBack(char *event)   
  246. {   
  247. if( (event == NULL)?1:(strlen(event) == 0)) return;   
  248. for(int i = 0; i < lastpos; i++)  
  249. if(callBackList[i] == event) callBackList[i].Flush();   
  250. }   
  251. void CallBack::CallCallBack(char *event, CallData callData)   
  252. {   
  253. if( (event == NULL)?1:(strlen(event) == 0)) return;    
  254. CallBack *pCBO;   
  255. CallBackFunction pCBF;   
  256. CallBackStaticFunction pCBSF;   
  257. MoveFirst();   
  258. while(!EndOfList())   
  259. {   
  260. //如當前事件記錄和指定事件不匹配,轉入下一條記錄繼續循環   
  261. if(!(callBackList[curpos] == event))   
  262. {   
  263. MoveNext();   
  264. continue;   
  265. }   
  266. //如找到匹配記錄   
  267. pCBO = callBackList[curpos].pointerToCBO;   
  268. //如事件記錄中回調對象指針為空,說明該記錄中保存的是靜態函數指針   
  269. if(pCBO == NULL){   
  270. pCBSF = callBackList[curpos].pointerToCBSF;   
  271. pCBSF(callData);//調用該靜態回調函數   
  272. }   
  273. else //如事件記錄中回調對象指針非空,說明該記錄中保存的是成員函數指針   
  274. {   
  275. pCBF = callBackList[curpos].pointerToCBF;   
  276. (pCBO->*pCBF)(callData);// 調用該回調對象的成員函數   
  277. }   
  278. MoveNext();   
  279. }   

【編輯推薦】

  1. C++對象傳遞實際應用問題解疑
  2. c++編程常用工具
  3. 程序員必看 c++筆試題匯總
  4. 編程必讀 15個編程好習慣
  5. c++最基礎的20條規則
責任編輯:韓亞珊 來源: 天極網
相關推薦

2010-01-28 09:54:27

C++程序設計

2011-07-10 15:36:54

C++

2010-01-27 14:24:15

C++程序設計

2010-01-13 18:30:18

CC++程序設計

2010-01-11 17:43:23

C++程序設計

2010-01-11 10:34:22

C++程序

2010-01-08 16:10:59

C++語言

2012-03-14 10:48:05

C#

2011-08-05 15:46:32

Objective-C 程序設計

2010-01-11 17:22:02

2011-07-05 16:05:43

面向對象編程

2011-07-05 15:22:04

程序設計

2011-07-05 15:59:57

面向對象編程

2009-09-02 13:22:23

C#組件化程序設計

2011-12-06 09:42:51

Java

2022-06-07 14:13:58

Simula編程語言GNU cim

2013-12-12 16:30:20

Lua腳本語言

2011-12-06 12:16:58

Java

2009-09-02 17:28:26

C#程序設計Windows窗體

2014-03-13 11:25:43

C++OpenCV
點贊
收藏

51CTO技術棧公眾號

日韩av无码中文字幕| 黄色一级视频片| 97国产精品久久久| 91精品国产乱码久久久久久久| 在线不卡的av| 日b视频免费观看| 色资源在线观看| 久久精品国产亚洲aⅴ| 欧美黑人xxx| 波多野吉衣中文字幕| 国产亚洲高清一区| 一本到高清视频免费精品| 一区二区三区在线视频111| 亚洲AV午夜精品| 日日夜夜精品视频天天综合网| 美日韩精品视频免费看| 大黑人交xxx极品hd| 91精品视频一区二区| 黄色一区二区在线| 好吊色这里只有精品| 免费在线高清av| 国产精品白丝av| 国产精品老女人视频| 国产精品自拍视频一区| 国产精品99视频| 精品国产露脸精彩对白 | 国模吧精品人体gogo| 精品午夜一区二区三区在线观看| 91福利视频在线观看| 在线看的片片片免费| 亚洲影院天堂中文av色| 精品sm在线观看| 伊人影院综合在线| 都市激情亚洲一区| 亚洲一区二区欧美| 自拍偷拍视频在线| 91在线免费看| 91偷拍与自偷拍精品| 国产99在线免费| 国产免费久久久| 美女视频一区在线观看| 国产91网红主播在线观看| 日本一二三区视频| 欧美91视频| 欧美成人激情视频| 熟女少妇a性色生活片毛片| 欧美一二区在线观看| 精品一区二区三区四区在线| 好吊操视频这里只有精品| 国产资源一区| 欧美性感一类影片在线播放| 欧美一级黄色片视频| 高清在线视频不卡| 天天影视网天天综合色在线播放| www婷婷av久久久影片| 成人国产免费电影| 亚洲欧美日韩国产综合在线| 中日韩在线视频| 欧洲日本在线| 亚洲欧美激情在线| 一区二区三区av在线| 尤物在线视频| 最新成人av在线| 中文字幕中文字幕一区三区| 美女av在线播放| 国产精品国产三级国产aⅴ中文| 图片区小说区区亚洲五月| 人妻巨大乳一二三区| 美女洗澡无遮挡| 日日夜夜精品视频| 欧美r级电影在线观看| 一区二区三区四区影院| 六月丁香久久丫| 亚洲欧美激情精品一区二区| 欧美熟妇一区二区| 秋霞欧美视频| 欧美成人黑人xx视频免费观看| 欧美成人精品欧美一级| 1024日韩| 欧洲日韩成人av| 亚洲精品国产精品国自产网站按摩| 免费黄网站欧美| 亚洲aⅴ男人的天堂在线观看| 国产成人精品一区二三区四区五区 | 日韩漫画puputoon| 麻豆精品一区二区综合av| 国产精品久久久久久久app| 精品国产www| 国产精品资源网站| 精品一区国产| 亚洲精品承认| 亚洲男人天堂av| 国产不卡一区二区视频| 欧美色999| 日韩一区二区中文字幕| 成人无码www在线看免费| 国产欧美久久一区二区三区| www.99久久热国产日韩欧美.com| 国产一级理论片| 久久综合九色综合欧美狠狠| 91久久精品国产| 午夜视频福利在线| 国产精品久久久久久久岛一牛影视 | 亚洲第一免费视频| 国产调教视频一区| 91网站在线观看免费| 国产另类xxxxhd高清| 日韩一区二区三区三四区视频在线观看| 国产xxxxxxxxx| 久久亚洲成人| 69av在线视频| 国产成人无码专区| 国产成人亚洲综合a∨婷婷图片| 久久精品日韩| av在线麻豆| 欧美性感一类影片在线播放| 最近中文字幕无免费| 亚洲国产老妈| 国产精品久久久av久久久| 亚洲av无码乱码国产精品久久| 欧美激情一区二区| 老太脱裤让老头玩ⅹxxxx| 成人午夜在线| 亚洲石原莉奈一区二区在线观看| 免费在线观看亚洲| 老鸭窝一区二区久久精品| 美女精品国产| f2c人成在线观看免费视频| 欧美久久久久免费| 久操视频在线观看免费| 国产精品五区| 国产一区二区三区免费不卡| 国产黄色在线观看| 欧美日韩一卡二卡| 69精品无码成人久久久久久| 亚洲精品日韩久久| av一区观看| 午夜成年人在线免费视频| 欧美日韩国产123区| 亚洲成人网在线播放| 亚洲专区在线| 精品一区二区三区国产| 国产白丝在线观看| 精品女同一区二区| 久草视频在线免费看| 国产精品亚洲一区二区三区妖精| 中文字幕中文字幕在线中一区高清 | 国产老妇伦国产熟女老妇视频| 中文字幕第一区综合| 老熟妇仑乱视频一区二区| 欧美一区 二区| 韩国欧美亚洲国产| 婷婷开心激情网| 欧美日韩一区二区在线播放| 欧美在线一级片| 亚洲精品人人| 久久久综合香蕉尹人综合网 | 日韩免费观看高清| 欧美3p视频在线观看| 色先锋资源久久综合| 波多野吉衣中文字幕| 日韩黄色片在线观看| 欧美尤物一区| 国产极品一区| 久久视频在线免费观看| 精品人妻伦一二三区久久| 亚洲精品视频观看| 欧美xxxxx精品| 美女精品网站| 亚洲一区二区三区加勒比 | 新91视频在线观看| 日韩电影一区二区三区四区| 亚洲高清视频一区| 国产精品一区二区三区四区在线观看| 操日韩av在线电影| 蜜桃视频污在线观看| 欧美午夜电影在线| 欧美性受xxxx黑人| 国产精品99久久久久久久女警| 欧美一区二区激情| 韩国三级在线观看久| 亚洲经典视频在线观看| 成人美女免费网站视频| 性网站在线观看| 日韩毛片中文字幕| 一级黄色a毛片| 亚洲国产裸拍裸体视频在线观看乱了| 国产精品无码永久免费不卡| 免费观看在线综合| 污污污污污污www网站免费| 欧美男男freegayvideosroom| 国产成人涩涩涩视频在线观看| 国产福利在线播放麻豆| 亚洲精品国产美女| 91麻豆成人精品国产| 亚洲综合免费观看高清完整版在线| 久久精品综合视频| 精品在线视频一区| 成人免费在线小视频| 亚洲91精品| 精品在线不卡| 国产精品亚洲欧美日韩一区在线 | 视频在线观看一区| 国产精品一区在线免费观看| 天堂资源在线亚洲| 亚洲伊人第一页| 惠美惠精品网| 久久国产色av| 能在线看的av| 精品国精品自拍自在线| 午夜一区二区三区四区| 亚洲国产欧美日韩另类综合 | 五月天婷婷在线观看| 欧美日韩日本视频| 可以免费看的av毛片| 综合电影一区二区三区 | 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 久久久久综合| 免费看黄色a级片| 青草国产精品| 美脚丝袜一区二区三区在线观看| 亚洲精品v亚洲精品v日韩精品| 国产精品人成电影在线观看| 黄色漫画在线免费看| 欧美另类xxx| 欧美被日视频| 最近2019中文字幕在线高清| 五月婷婷久久久| 精品日韩一区二区三区| 国产免费不卡av| 精品污污网站免费看| 国产污视频网站| 精品福利在线视频| 久久久久久久久久久久久久免费看| 中文字幕视频一区| 亚洲熟女少妇一区二区| 日本一区二区三区视频视频| 精品人妻一区二区三区香蕉| 93久久精品日日躁夜夜躁欧美| 韩国三级视频在线观看| 国产精品一色哟哟哟| 黄色aaaaaa| 国产一区二区三区在线看麻豆| 污视频免费在线观看网站| 天堂午夜影视日韩欧美一区二区| 草草久久久无码国产专区| 亚洲国产免费| 日韩精品 欧美| 亚洲三级毛片| 久在线观看视频| 亚洲一区自拍| 激情内射人妻1区2区3区| 米奇777在线欧美播放| 久久久久久久久久久福利| 一本色道88久久加勒比精品| 久艹视频在线免费观看| 9国产精品视频| 国产乱子伦农村叉叉叉| 日韩天堂av| 国产淫片av片久久久久久| 老**午夜毛片一区二区三区| 99视频精品免费| 青青草一区二区三区| 在线观看高清免费视频| 理论片日本一区| 极品人妻一区二区| 成人白浆超碰人人人人| 国产男女猛烈无遮挡a片漫画| 久久久精品综合| 精品伦精品一区二区三区视频密桃 | 激情成人综合| 37pao成人国产永久免费视频| 日韩二区三区四区| 中文字幕一区二区在线观看视频 | 成人激情视频在线| 日韩在线观看中文字幕| 国产一区二区在线观看免费播放| 色婷婷久久久| 神马影院一区二区三区| 91不卡在线观看| 国产精品国产亚洲精品看不卡| 免费视频久久| 日韩av片免费观看| 成人精品免费网站| 一区二区三区伦理片| 亚洲四区在线观看| 日韩污视频在线观看| 欧美亚洲自拍偷拍| 亚洲精品久久久久久无码色欲四季 | 日韩黄色大片| 日韩a级黄色片| 亚洲欧美日韩专区| 中文字幕一区二区在线观看视频| 成人avav在线| 在线观看天堂av| 亚洲成人动漫一区| 怡春院在线视频| 亚洲成人精品久久久| eeuss影院www在线播放| 欧美黑人xxx| 精品国产美女a久久9999| 国产精品大全| 天天影视综合| 亚洲午夜无码av毛片久久| 国产一区二区在线影院| 中文字幕一区二区三区人妻电影| 亚洲精品免费在线| 亚洲天堂日韩av| 日韩午夜激情视频| www.国产精品.com| 午夜精品一区二区三区在线播放| 久久免费资源| 麻豆成人在线播放| 欧美成熟视频| 91女神在线观看| 99国内精品久久| 男人晚上看的视频| 精品成人乱色一区二区| 精品国产亚洲av麻豆| 色黄久久久久久| 成人性生交大片免费观看网站| 97人人香蕉| 欧美激情理论| 欧美黄色性生活| 99riav一区二区三区| 久久久久久免费观看| 欧美精品三级日韩久久| www.亚洲资源| 国产精品免费视频xxxx| 九九在线精品| 成人黄色片视频| 91欧美一区二区| 一区二区三区视频免费看| 欧美电影免费观看完整版| 中文字幕在线观看网站| 成人免费网站在线观看| 日韩在线视频精品| 男女视频在线看| 国产清纯白嫩初高生在线观看91 | 久久久久久亚洲中文字幕无码| 亚洲高清不卡在线观看| 丰满人妻一区二区| 欧美激情2020午夜免费观看| 国产午夜久久av| 水蜜桃在线免费观看| 国内精品写真在线观看| 天天操夜夜操av| 日韩午夜在线播放| 啪啪免费视频一区| 国产欧美综合精品一区二区| 亚洲视频一区| 国产激情第一页| 调教+趴+乳夹+国产+精品| 日本在线视频1区| 日本久久久久久久久| 国产精品片aa在线观看| 九九热免费精品视频| 国产精品人妖ts系列视频| 中文字幕在线日亚洲9| 日韩在线精品一区| 国产精品日韩精品在线播放 | 中中文字幕av在线| 91原创国产| 亚洲激情不卡| 人妻熟女aⅴ一区二区三区汇编| 欧美日韩亚洲天堂| 成年人视频在线免费观看| 国产女同一区二区| 欧美不卡一区| 精品人妻少妇嫩草av无码| 在线观看视频欧美| 美女黄视频在线观看| 粉嫩av四季av绯色av第一区| 99精品国产在热久久婷婷| av直播在线观看| 欧美日韩亚洲不卡| 色婷婷视频在线观看| 精品在线视频一区二区| 秋霞国产午夜精品免费视频| 天天综合天天做| 日韩成人中文字幕在线观看| 成人软件在线观看| 水蜜桃在线免费观看| 久久先锋影音av| 国产精品国产三级国产aⅴ| 欧美精品精品精品精品免费| 色吊丝一区二区| 色偷偷中文字幕| 欧美视频在线视频| 韩国av网站在线| 久久精品国产精品国产精品污| 久久国产精品99久久久久久老狼| 欧美交换国产一区内射| 精品视频偷偷看在线观看| 未满十八勿进黄网站一区不卡| 国产一级爱c视频| 亚洲欧洲99久久| 免费在线黄色网址| 99九九视频| 美女视频一区在线观看|