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

首頁 > 學院 > 開發設計 > 正文

C++消息連接的一種系統方法

2019-11-17 05:39:04
字體:
來源:轉載
供稿:網友

  用過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用來將回調函數注冊到事件對象的回調表中。它有兩個重載版本:

void CallBack::AddCallBack(char *event,CallBackFunction cbf,CallBack *p);

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用來刪除注冊在事件對象上的回調函數。它的三個重載版本依次為:

void CallBack::RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p);

void CallBack::RemoveCallBack(char *event,CallBackStaticFunction cbsf);

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

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

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

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

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

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

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


//測試程序文件:test.cpp

#include"callback.h"

//“揚聲器”類

class Speaker:public CallBack

{

PRivate:
 int volume;
public:
 Speaker(int v): volume(v) {}
void IncreaseVolume(int v) //增加音量成員函數
 {
  volume += v;
  if(volume > 20){ //“音量大于20”事件發生了
   //調用注冊在兩事件上的回調函數
   CallCallBack("音量改變了");
   CallCallBack("音量大于20", &volume);
 }
}

void DecreaseVolume(int v) //降低音量成員函數

{
 volume -= v;
 if(volume < 5){ //“音量小于5”事件發生了
 //調用注冊在兩事件上的回調函數
  CallCallBack("音量改變了");
  CallCallBack("音量小于5", &volume);
}

}

};

//“耳朵”類

class Ear : public CallBack

{
 public:
  static void Response(CallData callData) //對“音量改變”的反應
  {
   cout<<"音量改變了."<<endl;
  }

void HighVoiceResponse(CallData callData)//對高音的反應

{
 cout<<”喂!太吵了!現在音量是:"<<*((int *)callData)<<endl;
}

void LowVoiceResponse(CallData callData)// 對低音的反應

{
 cout<<"??!我聽不清了。現在音量是:"<<*((int *)callData)<<endl;
}

};

void main(void)

{
Speaker s(10); //現在音量為10
Ear e;

//為事件對象s注冊回調函數
s.AddCallBack("音量大于20”,(CallBackFunction)&Ear::HighVoiceResponse,&e);
s.AddCallBack("音量小于5”,(CallBackFunction)&Ear::LowVoiceResponse,&e);
s.AddCallBack("音量改變了",(CallBackStaticFunction)&Ear::Response);
s.IncreaseVolume(12);//將音量增加12,現在音量位22
s.DecreaseVolume(20);//將音量減少20,現在音量位2

}
  運行結果:

  音量改變了.

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

  音量改變了.

   ?。∥衣牪磺辶恕,F在音量是:2

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

//回調類的類結構:callback.h

#ifndef _CALLBACK_H

#define _CALLBACK_H

#include<stdlib.h>

#include<string.h>

#include<iostream.h>

#define CALLBACKLIST_INIT_SIZE 10

#define CALLBACKLIST_INCREMENT 5

class CallBack;

typedef void *CallData;//回調數據指針類型定義

typedef void (CallBack::*CallBackFunction)(CallData); //指向回調成員函數的指針

typedef void (*CallBackStaticFunction)(CallData); //指向靜態成員函數或普通函數的指針類型定義

class EventRecord{

private:

char *eventName; //回調事件名稱

CallBack *pointerToCBO;//指向回調對象的指針

//指向成員函數的指針和指向靜態成員函數(或普通函數)指針的共用體

union{

CallBackFunction pointerToCBF;

CallBackStaticFunction pointerToCBSF;

};

public:

EventRecord(void); //事件記錄類的缺省構造函數

//構造包含成員函數的事件記錄

EventRecord(char *ename,CallBack *pCBO,CallBackFunction pCBF);

//構造包含靜態成員函數或普通函數的事件記錄

EventRecord(char *ename,CallBackStaticFunction pCBSF);

~EventRecord(void);//析構事件記錄

void Operator = (const EventRecord& er);//重載賦值運算符

//判定當前事件記錄的事件名是否為ename

int operator == (char *ename) const;

//判定當前事件記錄是否和指定事件記錄相等

int operator == (const EventRecord& er) const;

void Flush(void); //將當前事件記錄清空

int IsEmpty(void) const;//判定事件記錄是否為空(即事件名是否為空)

friend class CallBack; //讓CallBack類能訪問EventRecord的私有成員;

};

class CallBack {

private:

EventRecord *callBackList; //回調事件表

int curpos; //當前事件記錄位置

int lastpos; //回調表中最后一空閑位置

int size; //回調表的大小

void MoveFirst(void) { curpos = 0; }//將當前記錄置為第一條記錄

void MoveNext(void) //將下一條記錄置為當前記錄

{

if(curpos == lastpos) return;

curpos++;

}

//判定回調表是否被遍歷完

int EndOfList(void) const { return curpos == lastpos; }

public:

CallBack(void);//構造函數

CallBack(const CallBack& cb);//拷貝構造函數

~CallBack(void);//析構函數

void operator = (const CallBack& cb);// 重載賦值運算符

//將回調對象的成員函數、靜態成員函數(或普通函數)

//注冊為事件對象的回調函數

void AddCallBack(char *event,CallBackFunction cbf,CallBack *p);

void AddCallBack(char *event,CallBackStaticFunction cbsf);

//刪除注冊在指定事件上的回調函數

void RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p);

void RemoveCallBack(char *event,CallBackStaticFunction cbsf);

void RemoveCallBack(char *event);// 刪除某事件的全部記錄

//執行注冊在某一事件上的所有回調函數

void CallCallBack(char *event, CallData calldata = NULL);

};

#endif

//回調類的實現:callback.cpp

#include"callback.h"

 //EventRecord類的實現

EventRecord::EventRecord(void)

{

eventName = NULL;

pointerToCBO = NULL;

//因為sizeof(CallBackFunction) > sizeof(CallBackStaticFunction)

pointerToCBF = NULL;

}

EventRecord::EventRecord(char *ename, CallBack *pCBO, CallBackFunction pCBF)

:pointerToCBO(pCBO), pointerToCBF(pCBF)

{

eventName = strdup(ename);

}

EventRecord::EventRecord(char *ename, CallBackStaticFunction pCBSF)

:pointerToCBO(NULL), pointerToCBSF(pCBSF)

{

eventName = strdup(ename);

}

EventRecord::~EventRecord(void)

{

if(eventName) delete eventName;

}

void EventRecord::operator = (const EventRecord& er)

{

if(er.eventName)

eventName = strdup(er.eventName);

else

eventName = NULL;

pointerToCBO = er.pointerToCBO;

pointerToCBF = er.pointerToCBF;

}

int EventRecord::operator == (char *ename) const

{

if((eventName == NULL)ename == NULL)

return eventName == ename;

else

return strcmp(eventName,ename) == 0;

}

int EventRecord::operator == (const EventRecord& er) const

{

return (er == eventName) /*er和eventname不能交換位置*/

&&(pointerToCBO == er.pointerToCBO)

&&(pointerToCBO ?

(pointerToCBF == er.pointerToCBF):

(pointerToCBSF == er.pointerToCBSF));

}

void EventRecord::Flush(void)

{

if(eventName){

delete eventName;

eventName = NULL;

}

pointerToCBO = NULL;

pointerToCBF = NULL;

}

int EventRecord::IsEmpty(void) const

{

if(eventName == NULL)

return 1;

else

return 0;

}

//Callback類的實現

CallBack::CallBack(void)

{

//按初始尺寸為回調表分配內存空間

callBackList = new EventRecord[CALLBACKLIST_INIT_SIZE];

if(!callBackList){

cerr<<"CallBack: memory allocation error."<<endl;

exit(1);

}

size = CALLBACKLIST_INIT_SIZE;

lastpos = 0;

curpos = 0;

}

CallBack::CallBack(const CallBack& cb): curpos(cb.curpos),lastpos(cb.lastpos),size(cb.size)

{

callBackList = new EventRecord[size];

if(!callBackList){

cerr<<"CallBack: memory allocation error."<<endl;

exit(1);

}

//一一復制各條事件記錄

for(int i = 0; i < size; i++) callBackList[i] = cb.callBackList[i];

}

void CallBack::operator = (const CallBack& cb)

{

curpos = cb.curpos;

lastpos = cb.lastpos;

size = cb.size;

delete [] callBackList;//刪除舊的回調表

callBackList = new EventRecord[size];//重新分配內存空間

if(!callBackList){

cerr<<"CallBack: memory allocation error."<<endl;

exit(1);

}

//一一復制各條事件記錄

for(int i = 0; i < size; i++) callBackList[i] = cb.callBackList[i];

}

CallBack::~CallBack(void)

{

delete [] callBackList;

}

void CallBack::AddCallBack(char *event, CallBackFunction pCBF, CallBack *pCBO)

{

//如事件名為空,退出

if( (event == NULL)?1:(strlen(event) == 0)) return;

//尋找因刪除事件記錄而產生的第一個空閑位置,并填寫新事件記錄

for(int start=0;start<lastpos;start++)

if(callBackList[start].IsEmpty()){

callBackList[start] = EventRecord(event,pCBO,pCBF);

break;

}

if(start < lastpos) return; //確實存在空閑位置

//沒有空閑位置,在回調表后追加新記錄

if(lastpos == size) //回調表已滿,需“伸長”

{

EventRecord *tempList = callBackList;//暫存舊回調表指針

//以一定的步長“伸長”回調表

callBackList = new EventRecord[size + CALLBACKLIST_INCREMENT];

if(!callBackList){

cerr<<"CallBack: memory allocation error."<<endl;

exit(1);

}

//復制舊回調表中的記錄

for(int i = 0; i < size; i++) callBackList[i] = tempList[i];

delete [] tempList;//刪除舊回調表

size += CALLBACKLIST_INCREMENT;//記下新回調表的尺寸

}

//構造新的事件記錄并將其填入回調表中

callBackList[lastpos] = EventRecord(event,pCBO,pCBF);

lastpos++;

}

void CallBack::AddCallBack(char *event,CallBackStaticFunction pCBSF)

{

if( (event == NULL)?1:(strlen(event) == 0)) return;

for(int start=0;start<lastpos;start++)

if(callBackList[start].IsEmpty()){

callBackList[start] = EventRecord(event,pCBSF);

break;

}

if(start < lastpos) return; //a hole is found

if(lastpos == size) //event list is insufficient

{

EventRecord *tempList = callBackList;

callBackList = new EventRecord[size + CALLBACKLIST_INCREMENT];



if(!callBackList){

cerr<<"CallBack: memory allocation error."<<endl;

exit(1);

}

for(int i = 0; i < size; i++) callBackList[i] = tempList[i];

delete [] tempList;

size += CALLBACKLIST_INCREMENT;

}



callBackList[lastpos] = EventRecord(event,pCBSF);

lastpos++;

}



//刪除注冊在指定事件上的成員函數

void CallBack::RemoveCallBack(char *event, CallBackFunction pCBF, CallBack *pCBO)

{

if( (event == NULL)?1:(strlen(event) == 0)) return;

EventRecord er(event,pCBO,pCBF);



for(int i = 0; i < lastpos; i++)

if(callBackList[i] == er) callBackList[i].Flush();

}



//刪除注冊在指定事件上的靜態成員函數或普通函數

void CallBack::RemoveCallBack(char *event,CallBackStaticFunction pCBSF)

{

if( (event == NULL)?1:(strlen(event) == 0)) return;

EventRecord er(event,pCBSF);



for(int i = 0; i < lastpos; i++)

if(callBackList[i] == er) callBackList[i].Flush();

}

//刪除注冊在指定事件上的所有回調函數

void CallBack::RemoveCallBack(char *event)

{

if( (event == NULL)?1:(strlen(event) == 0)) return;

for(int i = 0; i < lastpos; i++)

if(callBackList[i] == event) callBackList[i].Flush();

}



void CallBack::CallCallBack(char *event, CallData callData)

{

if( (event == NULL)?1:(strlen(event) == 0)) return;



CallBack *pCBO;

CallBackFunction pCBF;

CallBackStaticFunction pCBSF;



MoveFirst();

while(!EndOfList())

{

//如當前事件記錄和指定事件不匹配,轉入下一條記錄繼續循環

if(!(callBackList[curpos] == event))

{

MoveNext();

continue;

}

//如找到匹配記錄

pCBO = callBackList[curpos].pointerToCBO;

//如事件記錄中回調對象指針為空,說明該記錄中保存的是靜態函數指針

if(pCBO == NULL){

pCBSF = callBackList[curpos].pointerToCBSF;

pCBSF(callData);//調用該靜態回調函數

}

else //如事件記錄中回調對象指針非空,說明該記錄中保存的是成員函數指針

{

pCBF = callBackList[curpos].pointerToCBF;

(pCBO->*pCBF)(callData);// 調用該回調對象的成員函數

}

MoveNext();

}

}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
爽爽爽爽爽爽爽成人免费观看| 国产a级全部精品| 精品久久久999| 亚洲成人999| 久久久久久久久久国产| 亚洲偷欧美偷国内偷| 亚洲一区中文字幕在线观看| 日韩欧美aaa| 欧美成人免费观看| 日本高清不卡在线| 亚洲成人a级网| 91精品国产99久久久久久| 欧洲成人免费视频| 亚洲精品国产电影| 青草热久免费精品视频| 亚洲精品久久久久中文字幕二区| 亚洲欧美国产日韩中文字幕| 精品视频在线导航| 高清日韩电视剧大全免费播放在线观看| 欧美壮男野外gaytube| 亚洲精品久久久久久久久久久久| 日韩中文字幕第一页| 91精品视频大全| 欧美黄色三级网站| 青青精品视频播放| 国产精品热视频| 欧美又大又硬又粗bbbbb| 欧洲美女免费图片一区| 富二代精品短视频| 精品亚洲va在线va天堂资源站| 欧美在线国产精品| 欧美性理论片在线观看片免费| 国内伊人久久久久久网站视频| 久久精品国产成人精品| 国产精品成人国产乱一区| 欧美激情国产日韩精品一区18| 热久久视久久精品18亚洲精品| 国产精品久久久久久久久粉嫩av| 亚洲精品日韩在线| 一区二区三区视频观看| 欧美成人黄色小视频| 日韩成人激情影院| 欧美性xxxx极品高清hd直播| 欧美色图在线视频| 国产一区二区三区日韩欧美| 久久精品国产v日韩v亚洲| 久久精品视频网站| 日韩欧美中文字幕在线观看| 97视频免费在线看| 国产日韩中文在线| 欧洲成人免费视频| 秋霞av国产精品一区| 欧美激情一区二区三区成人| 69**夜色精品国产69乱| 欧美在线视频一区| 久久久免费电影| 91久久国产精品91久久性色| 北条麻妃99精品青青久久| 日韩免费在线播放| 在线观看国产成人av片| 亚洲国产精品久久久久| 欧美日韩亚洲一区二| 日韩福利视频在线观看| 欧美孕妇与黑人孕交| 亚洲人成电影网| 国语自产精品视频在线看一大j8| 久久久国产视频91| 久久影院中文字幕| 亚洲剧情一区二区| 国产精品久久久久久久av大片| 最近2019免费中文字幕视频三| 欧美日本高清视频| 欧美一级大胆视频| 久久久久99精品久久久久| 黄色成人av网| 日韩在线视频一区| 欧美激情2020午夜免费观看| 亚洲精品视频播放| 中文字幕精品影院| 国产91精品久久久久| 成人黄色中文字幕| 欧美中文字幕第一页| 亚洲成人av片在线观看| 日本高清不卡的在线| 亚洲精品一区二区三区不| 欧美另类极品videosbest最新版本| 久久99热精品| 亚洲韩国欧洲国产日产av| 在线免费观看羞羞视频一区二区| 久久国产精品电影| 国产欧美日韩免费| 国产精品视频一区二区三区四| 亚洲一区二区三区成人在线视频精品| 国产亚洲a∨片在线观看| 国产亚洲精品va在线观看| 亚洲欧美国产精品va在线观看| 国产网站欧美日韩免费精品在线观看| 欧美中文在线视频| 国产成人精品午夜| 8090理伦午夜在线电影| 91av网站在线播放| 久久久亚洲成人| 亚洲精品国产品国语在线| 成人精品久久av网站| 欧美亚洲成人网| 午夜精品久久久久久久白皮肤| 日韩在线激情视频| 欧美性猛交xxxx免费看久久久| 国产精品自产拍在线观看| 欧美激情久久久| 成人中文字幕+乱码+中文字幕| 亚洲影院色在线观看免费| 日韩成人免费视频| 国产精品免费福利| 热re91久久精品国99热蜜臀| 精品免费在线视频| 97在线视频免费播放| 欧美日韩一二三四五区| 欧美成人午夜激情视频| 久久亚洲精品视频| 亚洲男人天堂2019| 成人免费福利在线| 成人免费视频在线观看超级碰| 亚洲香蕉在线观看| 亚洲aⅴ男人的天堂在线观看| 91久热免费在线视频| 这里只有精品在线观看| 欧美理论片在线观看| 国产国产精品人在线视| 日韩免费在线观看视频| 久久久久这里只有精品| 久久久精品国产| 久久精品国产96久久久香蕉| 亚洲欧美中文日韩在线v日本| 日韩精品在线观看一区| 成人网欧美在线视频| 国产精品久久久久999| 亚洲无亚洲人成网站77777| 91久久嫩草影院一区二区| 欧美性猛交xxxx免费看久久久| 久久久久国产视频| 亚洲缚视频在线观看| 欧美性xxxx| 亚洲天堂男人天堂女人天堂| 国产亚洲激情视频在线| 久久精品在线播放| 国产小视频国产精品| 亚洲精品视频久久| 欧美丰满少妇xxxx| 国产91|九色| 国产一区二区日韩精品欧美精品| 亚洲电影免费观看高清完整版在线观看| 成人午夜在线影院| 国产精品自产拍高潮在线观看| 亚洲va久久久噜噜噜久久天堂| 日韩一区二区在线视频| 日韩欧美视频一区二区三区| 日韩av电影院| 成人免费视频xnxx.com| 国产精品视频自在线| 日韩一区二区av| 日韩美女毛茸茸| 亚洲黄色www网站| 一区二区三区视频免费在线观看|