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

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉,開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

boost 智能指針

Posted on 2010-08-25 18:35 S.l.e!ep.¢% 閱讀(1250) 評論(0)  編輯 收藏 引用 所屬分類: C++

正文

????????? 智能指針能夠使 C++ 的開發簡單化,主要是它能夠像其它限制性語言(如 C# VB )自動管理內存的釋放,而且能夠做更多的事情。

1、 ? 什么是智能指針

智能指針是一種像指針的 C++ 對象,但它能夠在對象不使用的時候自己銷毀掉。

我們知道在 C++ 中的對象不再使用是很難定義的,因此 C++ 中的資源管理是很復雜的。各種智能指針能夠操作不同的情況。當然,智能指針能夠在任務結束的時候刪除對象,除了在程序之外。

許多庫都提供了智能指針的操作,但都有自己的優點和缺點。 Boost 庫是一個高質量的開源的 C++ 模板庫,很多人都考慮將其加入下一個 C++ 標準庫的版本中。

Boost 提供了下面幾種智能指針:

shared_ptr<T>

本指針中有一個引用指針記數器,表示類型 T 的對象是否已經不再使用。 shared_ptr ? Boost 中提供普通的智能指針,大多數地方都使用 shared_ptr

scoped_ptr<T>

當離開作用域能夠自動釋放的指針。因為它是不傳遞所有權的。事實上它明確禁止任何想要這樣做的企圖!這在你需要確保指針任何時候只有一個擁有者時的任何一種情境下都是非常重要的。

intrusive_ptr<T>

? shared_ptr? 更好的智能指針,但是需要類型 ?T? 提供自己的指針使用引用記數機制。

weak_ptr<T>

一個弱指針,幫助 shared_ptr ? 避免循環引用。

shared_array<T>

? shared_ptr? 類似,用來處理數組的。

scoped_array<T>

? scoped_ptr? 類似,用類處理數組的。

下面讓我們看一個簡單的例子:

2、 ? 首先介紹: boost::scoped_ptr<T>

scoped_ptr? ?Boost? 提供的一個簡單的智能指針,它能夠保證在離開作用域后對象被釋放。

例子說明:本例子使用了一個幫助我們理解的類: ?CSample ,? 在類的構造函數、賦值函數、析構函數中都加入了打印調試語句。因此在程序執行的每一步都會打印調試信息。在例子的目錄里已經包含了程序中需要的 Boost 庫的部分內容,不需要下載其它內容(查看 Boost 的安裝指南)。

下面的例子就是使用 scoped_ptr? 指針來自動釋放對象的:

使用普通指針

使用 scoped_ptr? 指針

void ?Sample1_Plain()

{

??CSample * pSample( new ?CSample);

?? if ?(!pSample->Query() )

??// just some function...

??{

???? delete ?pSample;

???? return ;

??}

??pSample->Use();

?? delete ?pSample;

}

# include ?"boost/smart_ptr.h"

void ?Sample1_ScopedPtr()

{

??boost::scoped_ptr<CSample>

???????samplePtr( new ?CSample);

??if (!samplePtr->Query() )

??// just some function...

???? return ;???

??samplePtr->Use();

}

使用普通普通指針的時候,我們必須記住在函數退出的時候要釋放在這個函數內創建的對象。當我們使用例外的時候處理指針是特別煩人的事情(容易忘記銷毀它)。使用 scoped_ptr? 指針就能夠在函數結束的時候自動銷毀它,但對于函數外創建的指針就無能為力了。

優點:對于在復雜的函數種, 使用 scoped_ptr? 指針能夠幫助我們處理那些容易忘記釋放的對象。也因此在調試模式下如果使用了空指針,就會出現一個斷言。

優點

自動釋放本地對象和成員變量 [1] ,延遲實例化,操作 PIMPL RAII (看下面)

缺點

STL 容器里,多個指針操作一個對象的時候需要注意。

性能

使用 scoped_ptr? 指針,會增加一個普通指針。

3、 ? 引用指針計數器

引用指針計數器記錄有多少個引用指針指向同一個對象,如果最后一個引用指針被銷毀的時候,那么就銷毀對象本身。

shared_ptr? 就是 Boost 中普通的引用指針計數器,它表示可以有多個指針指向同一個對象,看下面的例子:

void? Sample2_Shared()

{

?? // (A) ? 創建 Csample 類的一個實例和一個引用。

??boost::shared_ptr<CSample> mySample( new ?CSample);

??printf("The Sample now has %i references\n", mySample.use_count());? // The Sample now has 1 references

?? // (B) ? 付第二個指針給它。

??boost::shared_ptr<CSample> mySample2 = mySample;? //? 現在是兩個引用指針。

??printf("The Sample now has %i references\n", mySample.use_count());

?? // (C)? 設置第一個指針為空。

??mySample.reset();

??printf("The Sample now has %i references\n", mySample2.use_count());?? //? 一個引用

??//? mySample2 離開作用域的時候,對象只有一個引用的時候自動被刪除。

}

在( A )中在堆棧重創建了 CSample 類的一個實例,并且分配了一個 shared_ptr 指針。對象 mySample 入下圖所示:

然后我們分配了第二個指針 mySample2 ,現在有兩個指針訪問同一個數據。

我們重置第一個指針(將 mySample 設置為空 ),程序中仍然有一個 Csample 實例, mySample2 有一個引用指針。

只要當最有一個引用指針 mySample2 退出了它的作用域之外, Csample 這個實例才被銷毀。

當然,并不僅限于單個 Csample 這個實例,或者是兩個指針,一個函數,下面是用 shared_ptr 的實例:

·????????? 用作容器中。

·????????? 用在PIMPL的慣用手法 (the pointer-to-implementation idiom?)。

·????????? RAII Resource-Acquisition-Is-Initialization)的慣用手法中。

·????????? 執行分割接口。

注意:如果你沒有聽說過 PIMPL (a.k.a. handle/body)? ?RAII ,可以找一個好的 C++ 書,在 C++ 中處于重要的內容,一般 C++ 程序員都應該知道(不過我就是第一次看到這個寫法)。智能指針只是一中方便的他們的方法,本文中不討論他們的內容。

PIMPL :如果必須包容一個可能拋異常的子對象,但仍然不想從你自己的構造函數中拋出異常,考慮使用被叫做 Handle Class Pimpl 的方法(“ Pimpl ”個雙關語: pImpl 或“ pointer to implementation ”)

4、 ? 主要特點

boost::shared_ptr? 有一些重要的特征必須建立在其它操作之上。

·????????? shared_ptr<T> 作用在一個未知類型上

當聲明或定義一個 shared_ptr<T> T 可能是一個未知的類型。例如你僅僅在前面聲明了 class T ,但并沒有定義 class T 。當我們要釋放這個指針的時候我們需要知道這個 T 具體是一個聲明類型。

·????????? shared_ptr<T> 作用在任意類型上

在這里本質上不需要制定 T 的類型(如從一個基類繼承下來的)

·????????? shared_ptr<T> 支持自己定義釋放對象的操作

如果你的類中自己寫了釋放方法,也可以使用。具體參照 Boost 文檔。

·????????? 強制轉換

如果你定義了一個 U* 能夠強制轉換到 T* (因為 T U 的基類),那么 shared_ptr<U> 也能夠強制轉換到 shared_ptr<T>

·????????? shared_ptr? 是線程安全的

(這種設計的選擇超過它的優點,在多線程情況下是非常必要的)

·????????? 已經作為一種慣例,用在很多平臺上,被證明和認同的。

5、? 例子:在容器中使用 shared_ptr

許多容器類,包括 STL ,都需要拷貝操作(例如,我們插入一個存在的元素到 list,vector, 或者 container 。)當拷貝操作是非常銷毀資源的時候(這些操作時必須的),典型的操作就是使用容器指針。

std::vector<CMyLargeClass *> vec;

vec.push_back( new CMyLargeClass("bigString") );

將內存管理的任務拋給調用者,我們能夠使用 shared_ptr 來實現。

typedef boost::shared_ptr<CMyLargeClass>??CMyLargeClassPtr;

std::vector<CMyLargeClassPtr> vec;

vec.push_back( CMyLargeClassPtr(new CMyLargeClass("bigString")) );

vector 被銷毀的時候,這個元素自動被銷毀了。當然,除非有另一個智能指針引用了它,則還本能被銷毀。讓我們看 Sample3 中的使用:

void ?Sample3_Container()

{

?? typedef ?boost::shared_ptr<CSample> CSamplePtr;

??// (A) create a container of CSample pointers:

??std::vector<CSamplePtr> vec;

??// (B) add three elements

??vec.push_back(CSamplePtr( new ?CSample));

??vec.push_back(CSamplePtr( new ?CSample));

??vec.push_back(CSamplePtr( new ?CSample));

??// (C) "keep" a pointer to the second:

??CSamplePtr anElement = vec[1];

??// (D) destroy the vector:

??vec.clear();

??// (E) the second element still exists

??anElement->Use();

??printf("done. cleanup is automatic\n");

??// (F) anElement goes out of scope, deleting the last CSample instance

}

6、? 使用 Boost 中的智能指針,什么是正確的使用方法

使用智能指針的一些操作會產生錯誤(突出的事那些不可用的引用計數器,一些對象太容易釋放,或者根本釋放不掉)。 Boost 增強了這種安全性,處理了所有潛在存在的危險,所以我們要遵循以下幾條規則使我們的代碼更加安全。

下面幾條規則是你應該必須遵守的:

規則一:賦值和保存? —— ? 對于智能指針來說,賦值是立即創建一個實例,并且保存在那里。現在智能指針擁有一個對象,你不能手動釋放它,或者取走它,這將幫助你避免意外地釋放了一個對象,但你還在引用它,或者結束一個不可用的引用計數器。

規則二:_ptr<T> 不是T* ? —— ? 恰當地說,不能盲目地將一個 T*? 和一個智能指針類型 T 相互轉換。意思是:

·????????? 當創建一個智能指針的時候需要明確寫出 ? __ptr<T> myPtr<new T>

·????????? 不能將 T* 賦值給一個智能指針。

·????????? 不能寫 ptr = NULL ,應該使用 ptr.reset()

·????????? 重新找回原始指針,使用 ptr.get() ,不必釋放這個指針,智能指針會去釋放、重置、賦值。使用 get() 僅僅通過函數指針來獲取原始指針。

·????????? 不能通過 T* 指向函數指針來代表一個 __ptr<T> ,需要明確構造一個智能指針,或者說將一個原始指針的所有權給一個指針指針。(見規則三)

·????????? 這是一種特殊的方法來認定這個智能指針擁有的原始指針。不過在 Boost:smart pointer programming techniques ? 舉例說明了許多通用的情況。

規則三:非循環引用 ? —— ? 如果有兩個對象引用,而他們彼此都通過一個一個引用指針計數器,那么它們不能釋放, Boost? 提供了 weak_ptr 來打破這種循環引用(下面介紹)。

規則四:非臨時的 ? share_ptr? —— ? 不能夠造一個臨時的 share_ptr 來指向它們的函數,應該命名一個局部變量來實現。(這可以使處理以外更安全, Boost share_ptr best practices ? 有詳細解說)。

7、? 循環引用

引用計數器是一種便利的資源管理機制,它有一個基本回收機制。但循環引用不能夠自動回收,計算機很難檢測到。一個最簡單的例子,如下:

struct ?CDad;

struct ?CChild;

typedef ?boost::shared_ptr<CDad>???CDadPtr;

typedef ?boost::shared_ptr<CChild>??CChildPtr;

struct ?CDad : public CSample

{

???CChildPtr myBoy;

};

struct ?CChild : public CSample

{

?CDadPtr myDad;

};

// a "thing" that holds a smart pointer to another "thing":

CDadPtr???parent( new ?CDadPtr);

CChildPtr child( new ?CChildPtr);

// deliberately create a circular reference:

parent->myBoy = child;

child->myDad = dad;

// resetting one ptr...

child.reset();

????????? parent ? 仍然引用 CDad 對象,它自己本身又引用 CChild 。整個情況如下圖所示:

如果我們調用 dad.reset() ,那么我們兩個對象都會失去聯系。但這種正確的離開這個引用,共享的指針看上去沒有理由去釋放那兩個對象,我們不能夠再訪問那兩個對象,但那兩個對象的確還存在,這是一種非常嚴重的內存泄露。如果擁有更多的這種對象,那么將由更多的臨界資源不能正常釋放。

??????? 如果不能解決好共享智能指針的這種操作,這將是一個嚴重的問題(至少是我們不可接受的)。因此我們需要打破這種循環引用,下面有三種方法:

A、??? 當只剩下最后一個引用的時候需要手動打破循環引用釋放對象。

B、??? Dad 的生存期超過 Child 的生存期的時候, Child 需要一個普通指針指向 Dad

C、?? 使用 boost::weak_ptr 打破這種循環引用。

方法 A B 并不是一個完美的解決方案,但是可以在不使用 weak_ptr 的情況下讓我們使用智能指針,讓我們看看 weak_ptr 的詳細情況。

8、 ? 使用 weak_ptr 跳出循環

強引用和弱引用的比較:

一個強引用當被引用的對象活著的話,這個引用也存在(就是說,當至少有一個強引用,那么這個對象就不能被釋放)。 boost::share_ptr 就是強引用。相對而言,弱引用當引用的對象活著的時候不一定存在。僅僅是當它存在的時候的一個引用。

boost::weak_ptr<T>? 是執行弱引用的智能指針。當你需要它的時候就可以使用一個強(共享)指針指向它(當對象被釋放的時候,它為空),當然這個強指針在使用完畢應該立即釋放掉,在上面的例子中我們能夠修改它為弱指針。

struct CBetterChild : public CSample

{

??weak_ptr<CDad> myDad;

??void BringBeer()

??{

????shared_ptr<CDad> strongDad = myDad.lock(); // request a strong pointer

????if (strongDad)??????????????????????// is the object still alive?

??????strongDad->SetBeer();

?? ??// strongDad is released when it goes out of scope.

????// the object retains the weak pointer

??}

};

9、 ? Intrusive_ptr ——輕量級共享智能指針

shared_ptr 比普通指針提供了更完善的功能。有一個小小的代價,那就是一個共享指針比普通指針占用更多的空間,每一個對象都有一個共享指針,這個指針有引用計數器以便于釋放。但對于大多數實際情況,這些都是可以忽略不計的。

intrusive_ptr ? 提供了一個折中的解決方案。它提供了一個輕量級的引用計數器,但必須對象本身已經有了一個對象引用計數器。這并不是壞的想法,當你自己的設計的類中實現智能指針相同的工作,那么一定已經定義了一個引用計數器,這樣只需要更少的內存,而且可以提高執行性能。

如果你要使用 intrusive_ptr? 指向類型 T ,那么你就需要定義兩個函數: intrusive_ptr_add_ref? intrusive_ptr_release 。下面是一個簡單的例子解釋如何在自己的類中實現:

#include "boost/intrusive_ptr.hpp"

// forward declarations

class CRefCounted;

namespace boost

{

????void intrusive_ptr_add_ref(CRefCounted * p);

????void intrusive_ptr_release(CRefCounted * p);

};

// My Class

class CRefCounted

{

??private:

????long????references;

????friend void ::boost::intrusive_ptr_add_ref(CRefCounted * p);

????friend void ::boost::intrusive_ptr_release(CRefCounted * p);

??public:

????CRefCounted() : references(0) {}???// initialize references to 0

};

// class specific addref/release implementation

// the two function overloads must be in the boost namespace on most compilers:

namespace boost

{

?inline void intrusive_ptr_add_ref(CRefCounted * p)

??{

????// increment reference count of object *p

????++(p->references);

??}

?inline void intrusive_ptr_release(CRefCounted * p)

??{

???// decrement reference count, and delete object when reference count reaches 0

???if (--(p->references) == 0)

?????delete p;

??}

} // namespace boost

????????

????????? 這是一個最簡單的(非線程安全)實現操作。但作為一種通用的操作,如果提供一種基類來完成這種操作或許很有使用價值,也許在其他地方會介紹到。

10、 ? scoped_array? ?shared_array

scoped_array ? ? shared_array 和上面講的 基本上相同,只不過 他們 是指向數組的。就像使用指針操作一樣使用 operator new[]? ,他們都重載了 operator new[] 。注意他們并不初始化分配長度。

11、 ? Boost 的安裝

www.boost.org 上下載最新版本的 boost ,然后解壓縮到你指定的目錄里,解壓縮后的文件目錄如下:

Boost\?????boost 的源文件和頭文件。

Doc\????????HTML 格式的文檔。

Lib\????????? 庫文件(不是必需的)

????????????? 其他文件(“ more\ ”里有其他資料)

添加目錄到我們自己的 IDE 里:

VC6 :在菜單 Tools/Options Directories tab, "Show Directories for... Include files",

VC7 ? 在菜單 Tools/Options,??Projects/VC++ directories, "Show Directories for... Include files".

Boost 的頭文件都在 boost\ 子目錄里,例如本文檔例子中有 #include "boost/smart_ptr.hpp" 。所以任何人當讀到年的源文件的時候就立刻知道你用到了 boost 中的智能指針。

12、 ? 關于本文檔中的例子

本文檔中的例子里有一個子目錄 boost\ 僅僅包含了本例子中使用到的一些頭文件,僅僅是為了你編譯這個例子,如果你需要下載完整的 boost 或者獲取更多的資源請到 www.boost.org

13、 ? VC6 min/max 的災難

當在 VC 中使用 boost 庫,或者其他庫的時候會有一些小的問題。

Windows 的頭文件中已經定義了 min? ?max 宏,所以在 STL 中的這兩個函數就調用不到了,例如在 MFC 中就是這樣,但是在 Boost 中,都是使用的 std:: 命名空間下的函數,使用 Windows 的函數不能夠接受不同類型的參數在模板中使用,但是許多庫都依賴這些。

雖然 Boost 盡量處理這些問題,但有時候遇到這樣的問題的時候就需要在自己的代碼中加入像下面的代碼在第一個 #include 前加入 #define _NOMINMAX

#define _NOMINMAX????????????// disable windows.h defining min and max as macros

#include "boost/config.hpp"??// include boosts compiler-specific "fixes"

using std::min;??????????????// makle them globally available

using std::max;

????????? 這樣操作并不是在任何時候都需要,而只有我們碰到使用了就需要加入這段代碼。

14、 ? 資源

獲取更多的信息,或者有問題可以查找如下資源:

·????????? Boost home page

·????????? Download Boost

·????????? Smart pointer overview

·????????? Boost users mailing list

·????????? Boost中的智能指針 ( 撰文??Bjorn Karlsson????翻譯??曾毅)

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲国产一区二区三区a毛片 | 亚洲一区免费| 久久亚洲综合网| 欧美有码在线观看视频| 中日韩在线视频| 亚洲精选久久| 99精品视频免费| 在线综合亚洲| 午夜免费日韩视频| 欧美一区二区三区视频免费播放| 亚洲欧美国产日韩中文字幕| 亚洲美女在线一区| 午夜影院日韩| 六月婷婷一区| 亚洲人成免费| 亚洲永久精品大片| 久久激情久久| 欧美福利在线| 国产精品欧美久久久久无广告| 国产精品美女一区二区在线观看| 国产欧美91| 日韩午夜av电影| 销魂美女一区二区三区视频在线| 久久久中精品2020中文| 亚洲二区精品| 亚洲一二三区在线观看| 久久精品人人做人人综合 | 亚洲一区二区三区四区中文| 午夜精品在线视频| 麻豆精品视频| 亚洲福利一区| 亚洲欧美日韩在线不卡| 久久综合一区二区| 国产精品视频不卡| 亚洲欧洲美洲综合色网| 欧美一区二区网站| 一本到高清视频免费精品| 久久久激情视频| 国产日韩精品一区二区三区在线| 亚洲区欧美区| 久久久久综合一区二区三区| 一本色道久久综合| 欧美大片18| 黄色成人在线网址| 久久精品在线| 亚洲一区二区久久| 欧美日韩美女| 亚洲精品一区二区三区婷婷月| 久久精品国产99| 亚洲视频大全| 欧美日韩一区二区三区| 91久久国产综合久久| 久久久久久成人| 亚洲免费婷婷| 国产精品每日更新| 亚洲尤物在线| 一本色道久久88亚洲综合88| 欧美风情在线观看| 亚洲精品影院| 亚洲精品免费电影| 欧美激情亚洲一区| 日韩亚洲欧美精品| 亚洲国产日韩在线| 欧美成人国产va精品日本一级| 亚洲第一精品夜夜躁人人爽| 久久综合久久综合久久| 久久久久国色av免费看影院| 一色屋精品视频在线看| 久久久噜噜噜久久中文字幕色伊伊 | 夜夜嗨av色一区二区不卡| 欧美日韩二区三区| 亚洲私人影吧| 亚洲午夜久久久久久久久电影网| 国产精品va在线播放| 亚洲欧美视频一区二区三区| 99国产麻豆精品| 国产精品免费观看视频| 欧美一区二区三区免费观看视频| 亚洲一区二区三区在线看| 国产日韩精品一区二区三区| 久久精品99久久香蕉国产色戒| 欧美制服第一页| 亚洲精品国产精品国自产在线 | 亚洲盗摄视频| 欧美精品日日鲁夜夜添| 亚洲先锋成人| 性感少妇一区| 亚洲国语精品自产拍在线观看| 亚洲精品乱码久久久久久久久| 欧美日韩亚洲一区二| 午夜精品久久久久久99热| 久久精品视频亚洲| 99精品国产在热久久| 亚洲欧美在线另类| 亚洲青色在线| 亚洲一区激情| 亚洲激情黄色| 亚洲一区二区三区免费观看| 国模精品一区二区三区| 亚洲三级影片| 激情久久久久久久| 99视频精品免费观看| 狠狠久久综合婷婷不卡| 亚洲精品中文字| 国内成人精品2018免费看| 亚洲高清自拍| 国产日韩精品一区二区| 亚洲精品小视频| 韩国三级电影一区二区| 一区二区三区精品| 亚洲人久久久| 欧美一区二区黄色| 亚洲午夜精品久久久久久浪潮| 久久久久一区二区三区| 亚洲欧美中文字幕| 免费观看国产成人| 免费高清在线视频一区·| 国产精品久久久久久久久借妻| 欧美aa在线视频| 国产免费成人在线视频| 99精品热视频| 99成人精品| 免费视频一区| 久久亚洲精品视频| 国产人成一区二区三区影院| 亚洲日韩中文字幕在线播放| 一区二区三区在线看| 欧美一区久久| 久久精品免费观看| 国产精品久久一区主播| 一区二区三区欧美视频| 亚洲精品专区| 欧美黑人在线观看| 91久久精品美女高潮| 亚洲福利视频一区二区| 久久精品人人爽| 久久九九精品99国产精品| 国产精品免费网站在线观看| 一区二区福利| 一区二区三欧美| 亚洲欧洲精品一区| 宅男精品视频| 欧美吻胸吃奶大尺度电影| 999亚洲国产精| 在线亚洲高清视频| 欧美日韩在线视频一区二区| 99视频一区二区三区| 亚洲五月六月| 国产精品免费小视频| 另类春色校园亚洲| 伊人天天综合| 欧美国产视频在线观看| 亚洲片在线资源| 一本大道久久a久久精二百| 欧美日韩一区二区视频在线观看 | 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 欧美成人a视频| 亚洲美女黄网| 午夜精品一区二区三区电影天堂| 国产精品久久| 欧美一级在线视频| 欧美阿v一级看视频| 亚洲精品久久久久久一区二区| 欧美激情a∨在线视频播放| av成人老司机| 久久久久在线观看| 99伊人成综合| 国内精品一区二区三区| 欧美freesex8一10精品| 亚洲图片欧美日产| 免费不卡在线观看av| 一二三区精品| 狠狠爱成人网| 欧美午夜精品一区| 久久成人18免费观看| 欧美国产欧美亚洲国产日韩mv天天看完整 | 国外成人免费视频| 欧美激情亚洲| 欧美伊人久久大香线蕉综合69| 亚洲二区在线| 久久精品国产免费| 亚洲精品一区二区三区四区高清| 国产精品久久福利| 久久综合一区| 性欧美xxxx大乳国产app| 亚洲国产精品一区制服丝袜| 欧美一区三区三区高中清蜜桃| 亚洲破处大片| 国产在线成人| 欧美午夜精品久久久久久久| 久久综合给合久久狠狠狠97色69| 中文在线资源观看网站视频免费不卡 | 国产视频在线观看一区二区三区| 玖玖在线精品| 亚洲欧美日韩网| 亚洲精品国产欧美| 欧美激情 亚洲a∨综合| 久久狠狠久久综合桃花| 一区二区三区久久| 亚洲精品一区二区三区av|