国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

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

C++智能指針實例詳解

2020-05-23 14:24:15
字體:
供稿:網(wǎng)友
這篇文章主要介紹了C++智能指針實例詳解,需要的朋友可以參考下
 
 

本文通過實例詳細闡述了C++關(guān)于智能指針的概念及用法,有助于讀者加深對智能指針的理解。詳情如下:

一、簡介

由于 C++ 語言沒有自動內(nèi)存回收機制,程序員每次 new 出來的內(nèi)存都要手動 delete。程序員忘記 delete,流程太復(fù)雜,最終導(dǎo)致沒有 delete,異常導(dǎo)致程序過早退出,沒有執(zhí)行 delete 的情況并不罕見。
用智能指針便可以有效緩解這類問題,本文主要講解參見的智能指針的用法。包括:std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、boost::shared_array、boost::weak_ptr、boost:: intrusive_ptr。你可能會想,如此多的智能指針就為了解決new、delete匹配問題,真的有必要嗎?看完這篇文章后,我想你心里自然會有答案。

下面就按照順序講解如上 7 種智能指針(smart_ptr)。
 
二、具體使用

1、總括

對于編譯器來說,智能指針實際上是一個棧對象,并非指針類型,在棧對象生命期即將結(jié)束時,智能指針通過析構(gòu)函數(shù)釋放有它管理的堆內(nèi)存所有智能指針都重載了“operator->”操作符,直接返回對象的引用,用以操作對象。訪問智能指針原來的方法則使用“.”操作符。

訪問智能指針包含的裸指針則可以用 get() 函數(shù)。由于智能指針是一個對象,所以if (my_smart_object)永遠為真,要判斷智能指針的裸指針是否為空,需要這樣判斷:if (my_smart_object.get())。

智能指針包含了 reset() 方法,如果不傳遞參數(shù)(或者傳遞 NULL),則智能指針會釋放當前管理的內(nèi)存。如果傳遞一個對象,則智能指針會釋放當前對象,來管理新傳入的對象。
我們編寫一個測試類來輔助分析:

class Simple { public: Simple(int param = 0) {  number = param;  std::cout << "Simple: " << number << std::endl;  } ~Simple() {  std::cout << "~Simple: " << number << std::endl; } void PrintSomething() {  std::cout << "PrintSomething: " << info_extend.c_str() << std::endl; } std::string info_extend; int number;};

2、std::auto_ptr

std::auto_ptr 屬于 STL,當然在 namespace std 中,包含頭文件 #include<memory> 便可以使用。std::auto_ptr 能夠方便的管理單個堆內(nèi)存對象。

我們從代碼開始分析:

void TestAutoPtr() {std::auto_ptr<Simple> my_memory(new Simple(1));  // 創(chuàng)建對象,輸出:Simple:1if (my_memory.get()) {              // 判斷智能指針是否為空my_memory->PrintSomething();          // 使用 operator-> 調(diào)用智能指針對象中的函數(shù)my_memory.get()->info_extend = "Addition";   // 使用 get() 返回裸指針,然后給內(nèi)部對象賦值my_memory->PrintSomething();          // 再次打印,表明上述賦值成功(*my_memory).info_extend += " other";      // 使用 operator* 返回智能指針內(nèi)部對象,然后用“.”調(diào)用智能指針對象中的函數(shù)my_memory->PrintSomething();          // 再次打印,表明上述賦值成功 }}                       //my_memory棧對象即將結(jié)束生命期,析構(gòu)堆對象Simple(1)

執(zhí)行結(jié)果為:

Simple: 1PrintSomething:PrintSomething: AdditionPrintSomething: Addition other~Simple: 1

上述為正常使用 std::auto_ptr 的代碼,一切似乎都良好,無論如何不用我們顯示使用該死的 delete 了。
 
其實好景不長,我們看看如下的另一個例子:

void TestAutoPtr2() { std::auto_ptr<Simple> my_memory(new Simple(1)); if (my_memory.get()) {  std::auto_ptr<Simple> my_memory2;  // 創(chuàng)建一個新的 my_memory2 對象  my_memory2 = my_memory;       // 復(fù)制舊的 my_memory 給 my_memory2  my_memory2->PrintSomething();    // 輸出信息,復(fù)制成功  my_memory->PrintSomething();    // 崩潰 }}

最終如上代碼導(dǎo)致崩潰,如上代碼時絕對符合 C++ 編程思想的,居然崩潰了,跟進 std::auto_ptr 的源碼后,我們看到,罪魁禍首是“my_memory2 = my_memory”,這行代碼,my_memory2 完全奪取了 my_memory 的內(nèi)存管理所有權(quán),導(dǎo)致 my_memory 懸空,最后使用時導(dǎo)致崩潰。

所以,使用 std::auto_ptr 時,絕對不能使用“operator=”操作符。作為一個庫,不允許用戶使用,確沒有明確拒絕,多少會覺得有點出乎預(yù)料。
 
看完 std::auto_ptr 好景不長的第一個例子后,讓我們再來看一個:

void TestAutoPtr3() { std::auto_ptr<Simple> my_memory(new Simple(1));  if (my_memory.get()) {  my_memory.release(); }}

執(zhí)行結(jié)果為:

Simple: 1

看到什么異常了嗎?我們創(chuàng)建出來的對象沒有被析構(gòu),沒有輸出“~Simple: 1”,導(dǎo)致內(nèi)存泄露。當我們不想讓 my_memory 繼續(xù)生存下去,我們調(diào)用 release() 函數(shù)釋放內(nèi)存,結(jié)果卻導(dǎo)致內(nèi)存泄露(在內(nèi)存受限系統(tǒng)中,如果my_memory占用太多內(nèi)存,我們會考慮在使用完成后,立刻歸還,而不是等到 my_memory 結(jié)束生命期后才歸還)。

正確的代碼應(yīng)該為:

void TestAutoPtr3() { std::auto_ptr<Simple> my_memory(new Simple(1)); if (my_memory.get()) {  Simple* temp_memory = my_memory.release();  delete temp_memory; }}

void TestAutoPtr3() { std::auto_ptr<Simple> my_memory(new Simple(1)); if (my_memory.get()) {  my_memory.reset(); // 釋放 my_memory 內(nèi)部管理的內(nèi)存 }}

原來 std::auto_ptr 的 release() 函數(shù)只是讓出內(nèi)存所有權(quán),這顯然也不符合 C++ 編程思想。
總結(jié):std::auto_ptr 可用來管理單個對象的對內(nèi)存,但是,請注意如下幾點:

(1)    盡量不要使用“operator=”。如果使用了,請不要再使用先前對象。
(2)    記住 release() 函數(shù)不會釋放對象,僅僅歸還所有權(quán)。
(3)    std::auto_ptr 最好不要當成參數(shù)傳遞(讀者可以自行寫代碼確定為什么不能)。
(4)    由于 std::auto_ptr 的“operator=”問題,有其管理的對象不能放入 std::vector 等容器中。
使用一個 std::auto_ptr 的限制還真多,還不能用來管理堆內(nèi)存數(shù)組,這應(yīng)該是你目前在想的事情吧,我也覺得限制挺多的,哪天一個不小心,就導(dǎo)致問題了。
由于 std::auto_ptr 引發(fā)了諸多問題,一些設(shè)計并不是非常符合 C++ 編程思想,所以引發(fā)了下面 boost 的智能指針,boost 智能指針可以解決如上問題。
讓我們繼續(xù)向下看。
 
3、boost::scoped_ptr

boost::scoped_ptr 屬于 boost 庫,定義在 namespace boost 中,包含頭文件 #include<boost/smart_ptr.hpp> 便可以使用。boost::scoped_ptr 跟 std::auto_ptr 一樣,可以方便的管理單個堆內(nèi)存對象,特別的是,boost::scoped_ptr 獨享所有權(quán),避免了 std::auto_ptr 惱人的幾個問題。
我們還是從代碼開始分析:

void TestScopedPtr() { boost::scoped_ptr<Simple> my_memory(new Simple(1)); if (my_memory.get()) {  my_memory->PrintSomething();  my_memory.get()->info_extend = "Addition";  my_memory->PrintSomething();  (*my_memory).info_extend += " other";  my_memory->PrintSomething();    my_memory.release();      // 編譯 error: scoped_ptr 沒有 release 函數(shù)  std::auto_ptr<Simple> my_memory2;  my_memory2 = my_memory;    // 編譯 error: scoped_ptr 沒有重載 operator=,不會導(dǎo)致所有權(quán)轉(zhuǎn)移 }}

首先,我們可以看到,boost::scoped_ptr 也可以像 auto_ptr 一樣正常使用。但其沒有 release() 函數(shù),不會導(dǎo)致先前的內(nèi)存泄露問題。其次,由于 boost::scoped_ptr 是獨享所有權(quán)的,所以明確拒絕用戶寫“my_memory2 = my_memory”之類的語句,可以緩解 std::auto_ptr 幾個惱人的問題。
    由于 boost::scoped_ptr 獨享所有權(quán),當我們真真需要復(fù)制智能指針時,需求便滿足不了了,如此我們再引入一個智能指針,專門用于處理復(fù)制,參數(shù)傳遞的情況,這便是如下的 boost::shared_ptr。
 
4、boost::shared_ptr

boost::shared_ptr 屬于 boost 庫,定義在 namespace boost 中,包含頭文件 #include<boost/smart_ptr.hpp> 便可以使用。在上面我們看到 boost::scoped_ptr 獨享所有權(quán),不允許賦值、拷貝,boost::shared_ptr 是專門用于共享所有權(quán)的,由于要共享所有權(quán),其在內(nèi)部使用了引用計數(shù)。boost::shared_ptr 也是用于管理單個堆內(nèi)存對象的。
我們還是從代碼開始分析:

void TestSharedPtr(boost::shared_ptr<Simple> memory) { // 注意:無需使用 reference (或 const reference) memory->PrintSomething(); std::cout << "TestSharedPtr UseCount: " << memory.use_count() << std::endl;} void TestSharedPtr2() { boost::shared_ptr<Simple> my_memory(new Simple(1)); if (my_memory.get()) {  my_memory->PrintSomething();  my_memory.get()->info_extend = "Addition";  my_memory->PrintSomething();  (*my_memory).info_extend += " other";  my_memory->PrintSomething(); }  std::cout << "TestSharedPtr2 UseCount: " << my_memory.use_count() << std::endl; TestSharedPtr(my_memory); std::cout << "TestSharedPtr2 UseCount: " << my_memory.use_count() << std::endl;  //my_memory.release();// 編譯 error: 同樣,shared_ptr 也沒有 release 函數(shù)}

執(zhí)行結(jié)果為:

Simple: 1PrintSomething:PrintSomething: AdditionPrintSomething: Addition otherTestSharedPtr2 UseCount: 1PrintSomething: Addition otherTestSharedPtr UseCount: 2TestSharedPtr2 UseCount: 1~Simple: 1

boost::shared_ptr 也可以很方便的使用。并且沒有 release() 函數(shù)。關(guān)鍵的一點,boost::shared_ptr 內(nèi)部維護了一個引用計數(shù),由此可以支持復(fù)制、參數(shù)傳遞等。boost::shared_ptr 提供了一個函數(shù) use_count() ,此函數(shù)返回 boost::shared_ptr 內(nèi)部的引用計數(shù)。查看執(zhí)行結(jié)果,我們可以看到在 TestSharedPtr2 函數(shù)中,引用計數(shù)為 1,傳遞參數(shù)后(此處進行了一次復(fù)制),在函數(shù)TestSharedPtr 內(nèi)部,引用計數(shù)為2,在 TestSharedPtr 返回后,引用計數(shù)又降低為 1。當我們需要使用一個共享對象的時候,boost::shared_ptr 是再好不過的了。
在此,我們已經(jīng)看完單個對象的智能指針管理,關(guān)于智能指針管理數(shù)組,我們接下來講到。
 
5、boost::scoped_array

boost::scoped_array 屬于 boost 庫,定義在 namespace boost 中,包含頭文件 #include<boost/smart_ptr.hpp> 便可以使用。
    boost::scoped_array 便是用于管理動態(tài)數(shù)組的。跟 boost::scoped_ptr 一樣,也是獨享所有權(quán)的。

我們還是從代碼開始分析:

void TestScopedArray() {   boost::scoped_array<Simple> my_memory(new Simple[2]); // 使用內(nèi)存數(shù)組來初始化   if (my_memory.get()) {    my_memory[0].PrintSomething();    my_memory.get()[0].info_extend = "Addition";    my_memory[0].PrintSomething();    (*my_memory)[0].info_extend += " other";      // 編譯 error,scoped_ptr 沒有重載 operator*    my_memory[0].release();               // 同上,沒有 release 函數(shù)    boost::scoped_array<Simple> my_memory2;    my_memory2 = my_memory;               // 編譯 error,同上,沒有重載 operator=   }  }

boost::scoped_array 的使用跟 boost::scoped_ptr 差不多,不支持復(fù)制,并且初始化的時候需要使用動態(tài)數(shù)組。另外,boost::scoped_array 沒有重載“operator*”,其實這并無大礙,一般情況下,我們使用 get() 函數(shù)更明確些。

下面肯定應(yīng)該講 boost::shared_array 了,一個用引用計數(shù)解決復(fù)制、參數(shù)傳遞的智能指針類。
 
6、boost::shared_array
boost::shared_array 屬于 boost 庫,定義在 namespace boost 中,包含頭文件 #include<boost/smart_ptr.hpp> 便可以使用。

由于 boost::scoped_array 獨享所有權(quán),顯然在很多情況下(參數(shù)傳遞、對象賦值等)不滿足需求,由此我們引入 boost::shared_array。跟 boost::shared_ptr 一樣,內(nèi)部使用了引用計數(shù)。

我們還是從代碼開始分析:

void TestSharedArray(boost::shared_array<Simple> memory) { // 注意:無需使用 reference (或 const reference) std::cout << "TestSharedArray UseCount: " << memory.use_count() << std::endl;} void TestSharedArray2() { boost::shared_array<Simple> my_memory(new Simple[2]); if (my_memory.get()) {  my_memory[0].PrintSomething();  my_memory.get()[0].info_extend = "Addition 00";  my_memory[0].PrintSomething();  my_memory[1].PrintSomething();  my_memory.get()[1].info_extend = "Addition 11";  my_memory[1].PrintSomething();  //(*my_memory)[0].info_extend += " other"; // 編譯 error,scoped_ptr 沒有重載 operator* } std::cout << "TestSharedArray2 UseCount: " << my_memory.use_count() << std::endl; TestSharedArray(my_memory); std::cout << "TestSharedArray2 UseCount: " << my_memory.use_count() << std::endl;}

執(zhí)行結(jié)果為:

Simple: 0Simple: 0PrintSomething:PrintSomething: Addition 00PrintSomething:PrintSomething: Addition 11TestSharedArray2 UseCount: 1TestSharedArray UseCount: 2TestSharedArray2 UseCount: 1~Simple: 0~Simple: 0

跟 boost::shared_ptr 一樣,使用了引用計數(shù),可以復(fù)制,通過參數(shù)來傳遞。
 
至此,我們講過的智能指針有 std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、boost::shared_array。這幾個智能指針已經(jīng)基本夠我們使用了,90% 的使用過標準智能指針的代碼就這 5 種。可如下還有兩種智能指針,它們肯定有用,但有什么用處呢,一起看看吧。
 
7、boost::weak_ptr

boost::weak_ptr 屬于 boost 庫,定義在 namespace boost 中,包含頭文件 #include<boost/smart_ptr.hpp> 便可以使用。
在講 boost::weak_ptr 之前,讓我們先回顧一下前面講解的內(nèi)容。似乎 boost::scoped_ptr、boost::shared_ptr 這兩個智能指針就可以解決所有單個對象內(nèi)存的管理了,這兒還多出一個 boost::weak_ptr,是否還有某些情況我們沒納入考慮呢?
回答:有。首先 boost::weak_ptr 是專門為 boost::shared_ptr 而準備的。有時候,我們只關(guān)心能否使用對象,并不關(guān)心內(nèi)部的引用計數(shù)。boost::weak_ptr 是 boost::shared_ptr 的觀察者(Observer)對象,觀察者意味著 boost::weak_ptr 只對 boost::shared_ptr 進行引用,而不改變其引用計數(shù),當被觀察的 boost::shared_ptr 失效后,相應(yīng)的 boost::weak_ptr 也相應(yīng)失效。
我們還是從代碼開始分析:

  void TestWeakPtr() {   boost::weak_ptr<Simple> my_memory_weak;   boost::shared_ptr<Simple> my_memory(new Simple(1));    std::cout << "TestWeakPtr boost::shared_ptr UseCount: " << my_memory.use_count() << std::endl;   my_memory_weak = my_memory;   std::cout << "TestWeakPtr boost::shared_ptr UseCount: " << my_memory.use_count() << std::endl;}

    執(zhí)行結(jié)果為:

Simple: 1TestWeakPtr boost::shared_ptr UseCount: 1TestWeakPtr boost::shared_ptr UseCount: 1~Simple: 1

    我們看到,盡管被賦值了,內(nèi)部的引用計數(shù)并沒有什么變化,當然,讀者也可以試試傳遞參數(shù)等其他情況。
    現(xiàn)在要說的問題是,boost::weak_ptr 到底有什么作用呢?從上面那個例子看來,似乎沒有任何作用,其實 boost::weak_ptr 主要用在軟件架構(gòu)設(shè)計中,可以在基類(此處的基類并非抽象基類,而是指繼承于抽象基類的虛基類)中定義一個 boost::weak_ptr,用于指向子類的 boost::shared_ptr,這樣基類僅僅觀察自己的 boost::weak_ptr 是否為空就知道子類有沒對自己賦值了,而不用影響子類 boost::shared_ptr 的引用計數(shù),用以降低復(fù)雜度,更好的管理對象。
 
8、boost::intrusive_ptr

boost::intrusive_ptr屬于 boost 庫,定義在 namespace boost 中,包含頭文件 #include<boost/smart_ptr.hpp> 便可以使用。
講完如上 6 種智能指針后,對于一般程序來說 C++ 堆內(nèi)存管理就夠用了,現(xiàn)在有多了一種 boost::intrusive_ptr,這是一種插入式的智能指針,內(nèi)部不含有引用計數(shù),需要程序員自己加入引用計數(shù),不然編譯不過(⊙﹏⊙b汗)。個人感覺這個智能指針沒太大用處,至少我沒用過。有興趣的朋友自己研究一下源代碼哦。
 
 
三、總結(jié)

如上講了這么多智能指針,有必要對這些智能指針做個總結(jié):

1、在可以使用 boost 庫的場合下,拒絕使用 std::auto_ptr,因為其不僅不符合 C++ 編程思想,而且極容易出錯。
2、在確定對象無需共享的情況下,使用 boost::scoped_ptr(當然動態(tài)數(shù)組使用 boost::scoped_array)。
3、在對象需要共享的情況下,使用 boost::shared_ptr(當然動態(tài)數(shù)組使用 boost::shared_array)。
4、在需要訪問 boost::shared_ptr 對象,而又不想改變其引用計數(shù)的情況下,使用 boost::weak_ptr,一般常用于軟件框架設(shè)計中。
5、最后一點,也是要求最苛刻一點:在你的代碼中,不要出現(xiàn) delete 關(guān)鍵字(或 C 語言的 free 函數(shù)),因為可以用智能指針去管理。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
国产精品自拍亚洲| 青草av在线| 日本中文字幕高清视频| 国产精品免费视频一区一| 免费在线高清av| 超碰97在线免费观看| 亚洲精品自产拍在线观看| 天天操人人干| 最新天堂资源在线资源| 国产69久久| 中文字幕人成高视频| 爱福利在线视频| 天天操夜夜做| 国产尤物视频| 精品推荐蜜桃传媒| 久久精品视频免费看| 国产一区二区影视| 国产精品麻豆一区二区三区| 国产精品剧情一区二区三区| 国产精品自产拍在线网站| 久久国产综合视频| 天天爱天天色| 亚洲第一成年免费网站| 亚洲综合在线网| 欧美精品se| 天堂资源最新在线| av丝袜在线| 国产高清视频在线| 免费一区二区在线观看| 黄网址在线播放免费| 最近免费中文字幕大全免费第三页| 高清av在线| 国产黄视频网站| 超碰国产在线| 亚洲成人在线播放| 国产成人精品久久一区二区小说 | 超碰在线国产| 国产精选在线观看| 免费99热在线观看| 在线观看电影av| 国产经典av| 天堂在线视频| 91超碰在线免费| 最新中文字幕av专区| 久热免费在线视频| 国产福利片在线| 国产高清免费av在线| 国产精品午夜久久久久久| 亚洲视频手机在线观看| 国产精品久久久高清免费| 亚洲精品天堂在线观看| 国产精品区一区二| 国产精品作爱| 国产偷窥洗澡视频| 国产激情自拍| 伊人影院在线视频| 欧美日韩国产亚洲沙发| av片在线观看永久免费| 国产精品视频一区二区久久| 欧美性猛交xxxx免费看蜜桃| 亚洲激情丁香| 亚洲尤物在线视频| 青草av在线| 国产亚洲精品久久久久久青梅| 日本最新在线视频| 中文字幕日本在线观看| 福利视频网站导航| 国产在线高清| 伊人网站在线| 久久国产热视频| 国产国语**毛片高清视频| 91三级在线| 日本高清中文字幕| 国产乱xxⅹxx国语对白| 国产午夜在线| 精品美女在线观看视频在线观看| 国产精品va在线观看视色| 国产女主播在线| 精品视频一二三| 久久一本精品| 亚洲精品视频在线免费| 欧美日韩国产亚洲沙发| 青青青国产视频| 国产原创在线播放| 99爱视频在线观看| 国产偷倩在线播放| 国产在线观看a视频| 91蜜桃在线视频| www.狠狠| 精品国内一区二区三区免费视频| 麻豆精品传媒视频观看| 五月婷婷视频在线观看| 国产视频中文字幕在线观看| 国产精品伦一区二区三区视频| 在线免费观看高清视频色| 在线看黄色av| 国产超碰97| 国产成人综合美国十次| 国产免费av网站| 亚洲天堂久久久| 在线天堂中文| 在线观看国产视频| 国产成人亚洲欧美电影| 天堂在线一二区| 成年黄网站在线观看免费| 国产黄色免费看| 天天爱天天色| 国产永久av在线| 国产精品综合久久久久| 青青草免费在线视频| 在线伊人免费视频| 国产精品视频福利一区二区 | 四虎一区二区三区| 精品福利影院| 中文av字幕| 日日夜夜中文字幕| 免费一区二区在线观看| 欧美精品另类| 福利在线国产| 2019中文字幕在线视频| 18激情网站| 91亚洲天堂| 在线播放国产区| 青青国产在线| 国产小视频免费在线观看| 国产女主播在线观看| 国产视频资源| 国产精品扒开做爽爽爽的视频| 国产素人视频在线观看| 天堂亚洲精品| 操操操综合网| 1区2区视频| 毛片网站在线观看| 国产第一页在线| 国产在线观看av| 在线国产一级| 国产三级在线播放| 在线免费观看黄色av| 免费国产阿v视频在线观看| 久久精品亚洲7777影院| 中文字幕日本在线| 精品麻豆视频| 中文字幕亚洲免费| 日本片在线看| 在线免费国产视频| 国产区av在线| 国产在线视频福利| av中文在线资源| 国产网红在线| 国产在线视精品麻豆| aaa大片在线观看| 国产精品一区二区三区视频网站 | 九色福利视频| 国产成人无吗| 最近中文字幕mv免费高清视频8| 一本大道久久精品| 国产精品综合久久久久| 亚洲视频精品在线观看| 天堂资源在线中文| 成av人免费青青久| 日本在线观看| 四虎国产精品永久在线| 精品视频二区| 日本中文字幕在线看| 国产免费永久在线观看| 日本免费视频www| 在线观看精品一区二区三区| 国产激情网址| 国产三级在线看| 国产精品美女视频免费观看软件| 国产麻豆综合视频在线观看| а√最新版在线天堂| 伊人免费视频| 一本大道香蕉8中文在线视频| 国产福利在线视频| 日韩中文字幕久久久经典网| 国产三级做爰在线观看| 国产色婷婷在线| 国产精品白浆视频免费观看| 国产黄视频网站| 在线天堂中文www视软件| 精品国产二区三区| 91国内在线| 久久国产热视频| 国产丝袜精品丝袜| 亚洲精品天堂在线观看| 在线黄色国产电影| 欧美成人久久电影香蕉| 国产美女av| 国产网友自拍电影在线| 国产精品剧情一区二区三区| 国产丝袜精品丝袜| 国产黄色在线观看| 99精品老司机免费视频| 永久免费av网站| 欧美婷婷久久五月精品三区| 久久久久久久久久久久久91| 中文字幕在线观看播放| 7777在线| 黄色片视频在线观看|