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

Shuffy

不斷的學習,不斷的思考,才能不斷的進步.Let's do better together!
posts - 102, comments - 43, trackbacks - 0, articles - 19
[轉]http://m.shnenglu.com/tiandejian/archive/2007/10/04/ec_29.html

第29條:     力求使代碼做到“異常安全”

異常安全看上去像是孕育生命,但是請您先把這種觀點暫時放在腦后。因為在一對戀人結婚之前,討論生育問題還為時尚早。

假設我們正在設計一個表示 GUI 菜單的類,這種菜單是有背景圖片的,這個類用于多線程環(huán)境中,所以它擁有一個互斥鎖來確保正常的并發(fā)控制:

class PrettyMenu {

public:

 ...

 void changeBackground(std::istream& imgSrc); // 更改背景圖片

   ...

 

private:

 Mutex mutex;                   // 本對象使用的互斥鎖

 

 Image *bgImage;                // 當前的背景圖片

 int imageChanges;              // 圖片更改的次數(shù)

};

下面是 PrettyMenu changeBackground 函數(shù)實現(xiàn)的一個備選方案:

void PrettyMenu::changeBackground(std::istream& imgSrc)

{

 lock(&mutex);                  // 請求上鎖 ( 同第 14 )

 

 delete bgImage;                // 刪除舊的背景圖片

 ++imageChanges;                // 更新圖片改變的次數(shù)

 bgImage = new Image(imgSrc);   // 裝載新的背景圖片

 

 unlock(&mutex);                // 解鎖

}

從異常安全的角度來說,這個函數(shù)簡直一無是處。異常安全的兩個基本要求,這個函數(shù)完全沒有考慮到。

當拋出異常時,異常安全的代碼應該做到:

要泄漏資源。 上面的代碼沒有進行這項檢測,這是因為如果 new Image(imgSrc) 語句產生了異常 ,那么對 unlock 的調用則永遠不會兌現(xiàn),這樣互斥鎖將永遠不會被解開。

不能讓數(shù)據(jù)結構遭到破壞。 如果“ new Image(imgSrc) ”拋出異常, bgImage 就會指向一個已經銷毀的對象。另外,無論新的圖形是否裝載成功, imageChanges 的數(shù)值都會增加。(從另一個角度說,舊的圖形肯定是被刪除了,那么你又怎么能確保圖形被“改變”了呢。)

處理資源泄漏問題還是比較簡單的,因為第 13 條中介紹過如何使用對象來管理資源,第 14 條中介紹過如何通過 Lock 類確保互斥鎖在適當?shù)臅r候被解開:

void PrettyMenu::changeBackground(std::istream& imgSrc)

{

 Lock ml(&mutex);               // 來自第 14 條的經驗:

                                // 申請一個互斥鎖,并適時解鎖

 delete bgImage;

 ++imageChanges;

 bgImage = new Image(imgSrc);

}

能夠讓函數(shù)變得更短,是諸如 Lock 這樣的資源管理類最讓人興奮的事情之一。你是否注意到:這里甚至不需要調用 unlock 。更短的代碼就是更優(yōu)秀的代碼,因為代碼越短,它帶來錯誤和誤解的機會就越少。這是一條通用的準則。

把資源泄漏問題放在一旁,讓我們把注意力集中在數(shù)據(jù)結構破壞的問題上。這里我們可以進行一次選擇,但是在進行選擇之前,我們首先要了解所需要的幾個術語。

異常安全函數(shù)做出的保證可以總結為三個層面:

提供基本保證的函數(shù)會做出這樣的承諾:如果拋出了一個異常,那么程序中的一切都將保持合法的狀態(tài)。沒有任何對象或數(shù)據(jù)結構會遭到破壞,所有的對象的內部都保持協(xié)調的狀態(tài)(比如說所有類不變式都得到滿足)。然而,程序的具體狀態(tài)可能是無法預知的。比如說,我們可以這樣編 changeBackground :如果某一時刻拋出一個異常,那么 PrettyMenu 對象可能繼續(xù)使用舊的背景圖片,也可以用某個默認的背景圖片來代替。但是客戶端程序員無法做出任何預測。(為了找到答案,客戶端程序員大概會調用某個能告訴他們當前背景圖片是什么的成員函數(shù)。)

提供增強保證的函數(shù)會做出這樣的承諾:如果拋出了一個異常,那么函數(shù)的狀態(tài)將保持不變。這樣的函數(shù)看上去與原子有些相像,因為如果調用成功了,它就會大獲全勝;一旦出了差錯,那么就會一敗涂地,程序狀態(tài)將顯示它從來沒有被調用過。

使用提供強保證的的函數(shù)要比使用僅提供基本保證的函數(shù)簡單一些,這是因為在調用一個提供強保證的函數(shù)之后,程序只可能存在兩種狀態(tài):一、按預期進行,函數(shù)成功執(zhí)行;二、程序將保持函數(shù)調用前的狀態(tài)。反觀提供基本保證的函數(shù),如果在調用它時拋出了一個異常,那么程序可能會處于任何合法的狀態(tài)。

提供零異常保證的函數(shù)承諾程序決不會拋出異常,因為它們永遠都會按部就班的運行。所有的內建數(shù)據(jù)類型 int 、指針,等等)的操作都是零異常的(提供零異常保證)。這是異常安全代碼必不可少的一個因素。

我們可以假設包含空異常規(guī)范 [1] 的函數(shù)為零異常的,這樣做看上去是合理的,但是事實并不一定是這樣的,請看下面的函數(shù):

int doSomething() throw();          // 記錄空異常規(guī)范

這并不是說 doSomething 將永遠不會拋出異常,這只是說,如果 doSomething 拋出了異常,那么此時就出現(xiàn)了一個嚴重的錯誤,同時程序應該調用一個名為 unexpected 的函數(shù) [2] 。實際上, doSomething 可能根本不會提供任何異常保證。函數(shù)的聲明(包括它的異常規(guī)范,如果有的話)并不會告訴你它是否正確、是否小巧、是否高效,同時也不會告訴你它他提供了哪個層面上的異常安全保證。所有那些特性都要在函數(shù)實現(xiàn)中確定下來,而不是聲明中。

異常安全的代碼必須要提供上述三個層面的保證中的一種。否則它就不是異常安全的。那么你要做的就是:對于所寫的每一個函數(shù)都要確定使用哪一層面保證。除非我們正在處理沒有做到異常安全的糟糕代碼(這一點我們稍候再提)。只有當你的“優(yōu)秀”的需求分析小組提出:你的程序需要泄露資源,并且需要使用破壞的數(shù)據(jù)結構時,不提供任何異常安全保證也許才是一個可行的選擇。

作為一個通用的準則,你會希望提供可行范圍內最強化的保證。從異常安全的角度來說,零異常的函數(shù)是美妙的,但是如果不去調用拋出異常的函數(shù),你是很難逾越 C++ C 這一部分的。只要涉及動態(tài)內存分配(比如所有的 STL 容器),如果無法尋找到足夠的內存來滿足當前的要求,那么通常程序都會拋出一 bad_alloc 異常(參見第 49 條)。在可行的時候你應該為函數(shù)提供零異常保證,但是對于大多數(shù)函數(shù)而言,懸在是介于基本保證和增強保證之間的。

對于 changeBackground 而言,或多或少地提供增強保證并不是件難事。首先,我們可以改變 PrettyMenu bgImage 數(shù)據(jù)成員的類型,從一個內建的 Image* 指針類型轉變?yōu)橹悄苜Y源管理指針(參見第 13 條)。坦白的說,單獨從防止資源泄漏理論的角度上說,這是一個非常好的設計方案。事實上它簡單地通過使用對象(比如智能指針)來管理資源(也就是遵循了 13 條中的建議,這是優(yōu)秀設計的基本要求),幫助我們提供了增強的異常安全保證。在下面的代碼中,我將使用 tr1::shared_ptr ,這是因為它的行為更直觀,在進行復制操作時比 auto_ptr 更合適。

其次,我們從新編排了 changeBackground 中語句的順序,從而使 imageChanges 直到圖像改變以后才進行自加。作為一個通用的準則,直到一個事件真真切切地發(fā)生了,才去改變對象的狀態(tài)來描述這個事件。

下面是改進后的代碼:

class PrettyMenu {

 ...

 std::tr1::shared_ptr<Image> bgImage;

 ...

};

 

void PrettyMenu::changeBackground(std::istream& imgSrc)

{

 Lock ml(&mutex);

 

 bgImage.reset(new Image(imgSrc));   // bgImage 的內部指針替換為

                                      //”new Image” 表達式的結果

 ++imageChanges;

}

請注意這里不需要手動刪除舊圖片,因為這件事情完全由智能指針代勞了。而且,只有在新圖像成功創(chuàng)建之后,刪除操作才有意義。更精確地說, tr1::shared_ptr::reset 函數(shù)只有在其參數(shù)( ”new Image(imgSrc)” 的結果)成功創(chuàng)建以后才會得到調用。由于只有在調用 reset 過程中才會使用 delete ,因此如果從未進入該函數(shù),就永遠不會用到 delete 。注意:使用對象( tr1::shared_ptr )來管理資源(動態(tài)分配的 Image ),再次精簡了 changeBackground

如前所述,這兩項改變或多或少地使 changeBackground 滿足了增強的異常安全保證。可是 白璧微瑕, imgSrc 參數(shù) 還有 一個小問題。 如果 Image 的構造函數(shù)拋出了一個異常,那么輸入流的讀標記很可能會被移動,這樣的移動可能會造成狀態(tài)的變化,而這種變化對程序其它部分來說是可見的。在 changeBackground 指明這一問題之前,它僅僅提供基本的異常安全保證。

然而,讓我們把這個問題暫時放在一旁,假裝 changeBackground 確實可以提供增強保證。(我相信你可以想出一個辦法來,可以通過改變參數(shù)的類型:從輸入流變?yōu)榘瑘D像信息的文件名。)有一個一般化的設計方案,可以使函數(shù)做到增強保證,了解這種放案十分重要。這一方案一般稱為“復制并交換。”從理論上來講,它非常簡單。為需要修改的對象做一個副本,然后將所有需要的改變應用于這個副本之上。如果期間任一個修改操作拋出了異常,那么原始的對象依然紋絲未動。在所有改變順利完成之后,通過一次不拋出異常的操作將修改過的對象與原始對象相交換即可。

上述方案通常這樣實現(xiàn):將對象的所有數(shù)據(jù)從“真實的”對象復制到一個獨立實現(xiàn)的對象中,然后為真實對象創(chuàng)建一個指針,將其指向這個實現(xiàn)對象。這通常稱為“ pimpl idiom ”(指向實現(xiàn)的指針),第 31 條中將將解它的一些細節(jié)。對于 PrettyMenu 而言,典型的實現(xiàn)是這樣的:

struct PMImpl {                 // PMImpl = PrettyMenu 的實現(xiàn)

 std::tr1::shared_ptr<Image> bgImage;

 int imageChanges;              // 下文將介紹它為什么是結構體

};

 

class PrettyMenu {

 ...

 

private:

 Mutex mutex;

 std::tr1::shared_ptr<PMImpl> pImpl;

};

 

void PrettyMenu::changeBackground(std::istream& imgSrc)

{

 using std::swap;               // 參見第 25

 

 Lock ml(&mutex);               // 上鎖

 

 std::tr1::shared_ptr<PMImpl>   // 復制 對象數(shù)據(jù)

    pNew(new PMImpl(*pImpl));

 

 pNew->bgImage.reset(new Image(imgSrc));   // 修改副本

 ++pNew->imageChanges;

 

 swap(pImpl, pNew);             // 交換 新數(shù)據(jù)就位

 

}                               // 解鎖

在這個示例中,我做出了這樣的選擇: PMImpl 是一個結構體而不是類,這是因為 PrettyMenu 數(shù)據(jù)的封裝性是通過 pImpl 確定為私有的。將 PMImpl 實現(xiàn)為類不但不會帶來便利,而且效果也不好。(它同樣使面向對象的偏執(zhí)狂陷入絕境。)如果需要,可以把 PMImpl 放置在 PrettyMenu 的內部,但是打包問題與編寫異常安全代碼的問題似乎沒有什么聯(lián)系,這不是我們當前所關注的。

有些對象狀態(tài)修改的操作,要求要么是完全修改,要么完全不變,此時復制并交換策略是完美的。但是,一般情況下,它并不能確保整個函數(shù)都做到增強保證。請看下面 changeBackground 的一個抽象—— someFunc ,它使用了復制并交換策略,但是它包含了 2 個其它函數(shù)的調用:

void someFunc()

{

 ...                            // 為本地的狀態(tài)創(chuàng)建副本

 f1();

 f2();

 ...                            // 交換修改后的狀態(tài)就位

}

這里應該很清楚了:如 f1 或者 f2 沒有達到增強保證的要求,那么 someFunc 就很難滿足增強保證。比如,假設 f1 僅提供了基本保證,為了讓 someFunc 能滿足增強保證,就必須要為其編寫額外的代碼,用于調用 f1 之前確定整個程序的狀態(tài),捕獲 f1 拋出的所有異常,然后恢復原始的狀態(tài)。

如果 f1 f2 都滿足了增強保證,那么事情也不會好到哪去。如果 f1 運行完成,那么程序的狀態(tài)可能經歷了任意的修改過程,因此,如果 f2 在此時拋出了一個異常,那么程序的狀態(tài)就可能會與 someFunc 被調用時不一致,即使 f2 沒有做任何修改操作。

這個問題是個側面效應。只要函數(shù)操作僅僅針對本地的狀態(tài)(比如說, someFunc 僅僅影響到它所調用對象的狀態(tài)),提供增強保證就相對簡單些。當函數(shù)對于非本地數(shù)據(jù)存在這一側面效應時,則更加困難些。比如說,如果調用 f1 引入的側面效應是數(shù)據(jù)庫被修改了,那么讓 someFunc 滿足異常安全的增強保證就比較困難。一般來說,已經被系統(tǒng)接受的數(shù)據(jù)庫修改很難恢復,這是因為其它的數(shù)據(jù)庫用戶已經看到了數(shù)據(jù)庫的新狀態(tài)。

不管你情愿與否,諸如這樣的問題會為你在編寫增強保證的函數(shù)時設置重重障礙。另一個問題是:效率。復制并交換策略的核心思想就是修改對象副本的數(shù)據(jù),然后通過一個不會拋出異常地操作交換修改后的數(shù)據(jù)。這需要為每個需要修改的對象創(chuàng)建出一個副本,這樣做顯然會浪費時間和空間,你也許不會情愿使用這一策略,現(xiàn)實條件有時也會阻止你。增強保證是我們良好的預期目標,只要可行你就應該提供,但是現(xiàn)實中它并不總是可行的。

在增強保證不可行時,你應該提供基本保證。從實用角度說,如果你發(fā)現(xiàn)你可以為某些函數(shù)提供增強保證,但是由此帶來的效率和復雜度問題使得增強保證變得得不償失。只要你在必要的時候做出了努力使適當?shù)暮瘮?shù)滿足了增強保證,那么對于一些函數(shù)僅提供基本保證就是無可厚非的。對于大多數(shù)函數(shù)而言,基本保證已經是合理的、完美的選擇了。

如果你正在編寫一個完全不提供異常安全保證的函數(shù),那么就是另一番景象了。因為在這里完全可以在未證明你無罪之前假定你有罪。你本應該編寫異常安全代碼。但是你也可以為自己做出強有力的辯解。請再次考慮一下 someFunc 的實現(xiàn),它調用了兩個函數(shù): f1 f2 ,假設 f2 完全沒有提供異常安全保證,即使基本保證也沒有,這就意味著一旦 f2 拋出一個異常,程序可能會在 f2 的內部發(fā)生資源泄露。這意味著 f2 中可能會有破損的數(shù)據(jù)結構,比如:排好序的數(shù)組可能不再按順序排列,在兩個數(shù)據(jù)結構之間轉送的對象也可能會丟失數(shù)據(jù),等等。這樣 someFunc 也無力回天。如果 someFunc 函數(shù)調用了沒有提供異常安全保證的函數(shù),那么 someFunc 自身就無法做出任何保證。

讓我們回到本節(jié)開篇時所說的“孕育生命”的問題。一位女性要么就是懷孕,要么就是沒有,絕沒有“部分懷孕”的狀態(tài)。類似的,一個軟件系統(tǒng)要么是異常安全的,要么就不是。沒有所謂的“部分異常安全”的狀態(tài)存在。在一個系統(tǒng)中,即使只有一個單獨的函數(shù)不是異常安全的,那么整個系統(tǒng)也就不是異常安全的。遺憾的是,許多較為古老的 C++ 代碼在編寫的時候完全沒有考慮到異常安全問題,因此當今許多系統(tǒng)便不是異常安全的。新系統(tǒng)中混雜著異常不安全的編寫習慣。

沒有理由去維持現(xiàn)狀。當編寫新代碼或者修改現(xiàn)有代碼的時候,要認真考慮一下如何使之做到異常安全。首先,使用對象管理資源。(依然參見第 13 條。)這將有效地防止資源泄露。然后對于你要編寫的每個函數(shù)確定你要使用哪一層面的異常安全保證,只有在調用古老的、沒有異常安全保證的代碼時才放棄異常安全保證,因為你別無選擇。記錄下你的選擇,這即是為了你的客戶端程序員,也是為了今后的維護人員。函數(shù)的異常安全保證位于接口的可見部分,因此你應該認真規(guī)劃它,就像你認真規(guī)劃接口其它部分一樣。

四十年前,人們迷信充斥著 goto 的代碼是完美的,現(xiàn)在我們卻為了編寫結構化控制流而努力。二十年前,全局的完全可訪問的數(shù)據(jù)也是高踞神壇,然而當今我們卻在提倡封裝數(shù)據(jù)。十年前,編寫函數(shù)時不去考慮異常的影響的做法倍受追捧,但是今天,我們堅定不渝的編寫異常安全代碼。

歲月荏苒,我們在學習中不斷進步……

銘記在心

異常安全的函數(shù)即使在異常拋出時,也不會帶來資源泄露,同時也不允許數(shù)據(jù)結構遭到破壞。這類函數(shù)提供基本的、增強的、零異常的三個層面的異常安全保證。

增強保證可以通過復制并交換策略來實現(xiàn),但是增強保證并不是對所有函數(shù)都適用。

函數(shù)所提供的異常安全保證通常不要強于其調用的函數(shù)中保證層次最弱的一個。



[1] 異常規(guī)范是指:在函數(shù)聲明時列出該函數(shù)可能拋出的異常的類型,并確保該函數(shù)不會拋出其它類型的異常。——譯者注

[2] 關于 unexpected 函數(shù)的更多信息,你可以參考你最喜歡的搜索引擎,或者“ C++ 大全”一類的書籍。(搜 set_unexpected 可能會更好運些,因為它確定了 unexpected 性質)

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲高清在线播放| 一本色道久久综合亚洲二区三区| 韩国亚洲精品| 久久人人九九| 久久久久久一区二区| 久久综合久久88| 亚洲欧美国产日韩天堂区| 亚洲国产欧美一区二区三区久久 | 午夜在线一区| 亚洲砖区区免费| 亚洲欧美日韩国产成人| 亚洲国产精品黑人久久久| 国产精品成av人在线视午夜片| 欧美日韩成人综合在线一区二区| 欧美日韩精品伦理作品在线免费观看| 美女黄毛**国产精品啪啪 | 国产精品成人一区二区三区吃奶| 欧美激情成人在线| 国产精品久久久久久久久久免费 | 亚洲视频网在线直播| 午夜亚洲性色福利视频| 久久久精品性| 欧美一级精品大片| 久久精彩免费视频| 在线一区观看| 美女脱光内衣内裤视频久久影院| 亚洲国产激情| 午夜精品一区二区三区在线| 性欧美超级视频| 欧美女同视频| 亚洲福利视频网| 正在播放欧美一区| 久久精品国产欧美亚洲人人爽| 免费国产自线拍一欧美视频| 欧美激情一区三区| 欧美一区二区三区在线观看| 国产精品一区二区在线观看不卡| 激情欧美丁香| 欧美一区二区三区在线| 欧美一区二区三区免费视| 欧美黄色精品| 亚洲综合成人婷婷小说| 欧美在线观看一二区| 国产精品乱码妇女bbbb| 亚洲精品一区二区三区蜜桃久| 蜜臀久久99精品久久久久久9 | 先锋影音国产一区| 亚洲国产乱码最新视频| 国产精品国产三级国产aⅴ9色| 在线一区二区视频| 一本大道久久a久久精品综合| 久久久91精品国产一区二区三区| 久久国产一区| 亚洲国产精品v| 欧美激情一区在线观看| 91久久精品国产91久久性色tv| 欧美一区二区三区的| 久久久亚洲一区| 亚洲国产综合在线| 性做久久久久久免费观看欧美| 亚洲免费高清视频| 亚洲国产精品成人综合色在线婷婷| 久久人人爽人人爽爽久久| 免费欧美视频| 亚洲精品国产品国语在线app | 国产精品一二一区| 一本一道久久综合狠狠老精东影业| 久久久国产一区二区| 久久久久88色偷偷免费| 夜夜爽www精品| 亚洲摸下面视频| 99av国产精品欲麻豆| 香港久久久电影| 欧美成人精品福利| 红桃视频成人| 亚洲欧美久久久久一区二区三区| 在线观看视频日韩| 午夜精品久久久久久99热| 亚洲欧美一区二区三区极速播放| 久久综合狠狠综合久久综合88| 亚洲一区三区视频在线观看| 欧美日韩午夜在线视频| 欧美不卡在线| 影音先锋中文字幕一区二区| 中文亚洲欧美| 久久婷婷国产综合精品青草| 欧美日韩视频在线一区二区观看视频 | 亚洲女同性videos| 蜜臀a∨国产成人精品| 精品1区2区3区4区| 玖玖精品视频| 亚洲精品老司机| 9色porny自拍视频一区二区| 欧美日韩中文另类| 久久久久久综合| 宅男在线国产精品| 亚洲福利在线看| 久久另类ts人妖一区二区| 一本色道久久综合亚洲精品按摩 | 亚洲国产精品一区二区www| 亚洲一区二区三区中文字幕在线| 国产日韩成人精品| 欧美性色综合| 欧美视频在线观看| 欧美成人一区二区| 欧美成人三级在线| 麻豆精品视频在线观看| 亚洲欧美在线免费观看| 亚洲小说春色综合另类电影| 日韩视频一区二区三区在线播放免费观看 | 国产精品国产三级国产aⅴ浪潮 | 欧美在线电影| 久久精品视频在线播放| 久久精品国产精品亚洲综合| 亚洲神马久久| 亚洲午夜激情网站| 亚洲一二三区精品| 亚洲一区二区成人| 亚洲欧美日韩中文播放| 久久国产欧美日韩精品| 久久久一区二区| 亚洲激情网站| 亚洲免费视频一区二区| 欧美一区二区三区视频| 免费观看一级特黄欧美大片| 蜜桃av综合| 国产精品久久久久久久免费软件| 国产亚洲亚洲| 国产亚洲精品一区二555| 亚洲国产成人av好男人在线观看| 亚洲免费高清视频| 99成人在线| 亚洲综合好骚| 91久久精品一区| 亚洲欧美国产精品va在线观看| 久久精品国产99国产精品澳门| 欧美电影打屁股sp| 亚洲午夜一区二区| 欧美激情成人在线视频| 国产日韩欧美三级| 亚洲一区二区精品| 亚洲第一黄网| 久久久精品午夜少妇| 国产午夜精品麻豆| 亚洲综合日本| 日韩视频不卡| 欧美午夜宅男影院| 亚洲精品综合| 亚洲国产精品成人| 欧美激情偷拍| 亚洲精品在线三区| 亚洲国产一区在线| 欧美人成在线| 亚洲免费综合| 亚洲男同1069视频| 国产日本欧美一区二区三区| 久久成人精品电影| 亚洲欧美一级二级三级| 一本一本a久久| 欧美激情91| 亚洲欧美国产精品桃花| 亚洲欧美精品在线| 亚洲国产成人午夜在线一区| 亚洲国产日韩欧美在线图片| 欧美精品一卡| 久久se精品一区精品二区| 午夜精品久久久久久久久| 国产日韩欧美日韩大片| 欧美激情一区二区三区 | 久久se精品一区精品二区| 国产麻豆精品theporn| 欧美成人免费va影院高清| 欧美性大战久久久久| 麻豆精品视频| 国产欧美一区二区三区沐欲| 欧美高清在线视频| 国产精品视频999| 日韩视频在线播放| 亚洲高清免费在线| 亚洲欧美视频在线观看视频| 在线一区视频| 欧美精品一区二区三| 欧美成人午夜激情在线| 国产乱肥老妇国产一区二| 91久久在线| 亚洲欧洲精品一区二区三区| 久久爱另类一区二区小说| 午夜激情一区| 国产婷婷色综合av蜜臀av| 亚洲欧美国产高清va在线播| 亚洲欧美激情视频在线观看一区二区三区| 久久字幕精品一区| 亚洲国产另类精品专区| 亚洲人精品午夜在线观看| 老色批av在线精品| 亚洲国产精品尤物yw在线观看| 亚洲国产日韩欧美一区二区三区| 久久久青草婷婷精品综合日韩 | 亚洲性夜色噜噜噜7777| 欧美韩日高清|