日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ 智能指针最佳实践源码分析

發(fā)布時間:2024/2/28 c/c++ 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 智能指针最佳实践源码分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者:lucasfan,騰訊 IEG Global Pub.Tech. 客戶端工程師

智能指針在 C++11 標(biāo)準(zhǔn)中被引入真正標(biāo)準(zhǔn)庫(C++98 中引入的 auto_ptr 存在較多問題),但目前很多 C++開發(fā)者仍習(xí)慣用原生指針,視智能指針為洪水猛獸。但很多實(shí)際場景下,智能指針卻是解決問題的神器,尤其是一些涉及多線程的場景下。本文將介紹智能指針可以解決的問題,用法及最佳實(shí)踐。并且根據(jù)源碼分析智能指針的實(shí)現(xiàn)原理。

一、為什么需要使用智能指針

1.1 內(nèi)存泄漏

C++在堆上申請內(nèi)存后,需要手動對內(nèi)存進(jìn)行釋放。代碼的初創(chuàng)者可能會注意內(nèi)存的釋放,但隨著代碼協(xié)作者加入,或者隨著代碼日趨復(fù)雜,很難保證內(nèi)存都被正確釋放。

尤其是一些代碼分支在開發(fā)中沒有被完全測試覆蓋的時候,就算是內(nèi)存泄漏檢查工具也不一定能檢查到內(nèi)存泄漏。

void?test_memory_leak(bool?open) {A?*a?=?new?A();if(open){//?代碼變復(fù)雜過程中,很可能漏了?delete(a);return;}delete(a);return; }

1.2 多線程下對象析構(gòu)問題

多線程遇上對象析構(gòu),是一個很難的問題,稍有不慎就會導(dǎo)致程序崩潰。因此在對于 C++開發(fā)者而言,經(jīng)常會使用靜態(tài)單例來使得對象常駐內(nèi)存,避免析構(gòu)帶來的問題。這勢必會造成內(nèi)存泄露,當(dāng)單例對象比較大,或者程序?qū)?nèi)存非常敏感的時候,就必須面對這個問題了。

先以一個常見的 C++多線程問題為例,介紹多線程下的對象析構(gòu)問題。

比如我們在開發(fā)過程中,經(jīng)常會在一個 Class 中創(chuàng)建一個線程,這個線程讀取外部對象的成員變量。

//?日志上報Class class?ReportClass { private:ReportClass()?{}ReportClass(const?ReportClass&)?=?delete;ReportClass&?operator=(const?ReportClass&)?=?delete;ReportClass(const?ReportClass&&)?=?delete;ReportClass&?operator=(const?ReportClass&&)?=?delete;private:std::mutex?mutex_;int?count_?=?0;void?addWorkThread();public:void?pushEvent(std::string?event);private:static?void?workThread(ReportClass?*report);private:static?ReportClass*?instance_;static?std::mutex?static_mutex_;public:static?ReportClass*?GetInstance();static?void?ReleaseInstance(); };std::mutex?ReportClass::static_mutex_; ReportClass*?ReportClass::instance_;ReportClass*?ReportClass::GetInstance() {//?單例簡單實(shí)現(xiàn),非本文重點(diǎn)std::lock_guard<std::mutex>?lock(static_mutex_);if?(instance_?==?nullptr)?{instance_?=?new?ReportClass();instance_->addWorkThread();}return?instance_; }void?ReportClass::ReleaseInstance() {std::lock_guard<std::mutex>?lock(static_mutex_);if(instance_?!=?nullptr){delete?instance_;instance_?=?nullptr;} }//?輪詢上報線程 void?ReportClass::workThread(ReportClass?*report) {while(true){//?線程運(yùn)行過程中,report可能已經(jīng)被銷毀了std::unique_lock<std::mutex>?lock(report->mutex_);if(report->count_?>?0){report->count_--;}usleep(1000*1000);} }//?創(chuàng)建任務(wù)線程 void?ReportClass::addWorkThread() {std::thread?new_thread(workThread,?this);new_thread.detach(); }//?外部調(diào)用 void?ReportClass::pushEvent(std::string?event) {std::unique_lock<std::mutex>?lock(mutex_);this->count_++; }

使用 ReportClass 的代碼如下:

ReportClass::GetInstance()->pushEvent("test");

但當(dāng)這個外部對象(即ReportClass)析構(gòu)時,對象創(chuàng)建的線程還在執(zhí)行。此時線程引用的對象指針為野指針,程序必然會發(fā)生異常。

解決這個問題的思路是在對象析構(gòu)的時候,對線程進(jìn)行join。

//?日志上報Class class?ReportClass { private://...~ReportClass();private://...bool?stop_?=?false;std::thread?*work_thread_;//... };//?輪詢上報線程 void?ReportClass::workThread(ReportClass?*report) {while(true){std::unique_lock<std::mutex>?lock(report->mutex_);//?如果上報停止,不再輪詢上報if(report->stop_){break;}if(report->count_?>?0){report->count_--;}usleep(1000*1000);} }//?創(chuàng)建任務(wù)線程 void?ReportClass::addWorkThread() {//?保存線程指針,不再使用分離線程work_thread_?=?new?std::thread(workThread,?this); }ReportClass::~ReportClass() {//?通過join來停止內(nèi)部線程stop_?=?true;work_thread_->join();delete?work_thread_;work_thread_?=?nullptr; }

這種方式看起來沒問題了,但是由于這個對象一般是被多個線程使用。假如某個線程想要釋放這個對象,但另外一個線程還在使用這個對象,可能會出現(xiàn)野指針問題。就算釋放對象的線程將對象釋放后將指針置為nullptr,但仍然可能在多線程下在指針置空前被另外一個線程取得地址并使用。

線程 A線程 B
ReportClass::GetInstance()->ReleaseInstance();ReportClass *report = ReportClass::GetInstance();
if(report) {
// 此時切換到線程 A
report->pushEvent("test");
}

此種場景下,鎖機(jī)制已經(jīng)很難解決這個問題。對于多線程下的對象析構(gòu)問題,智能指針可謂是神器。接下來我們先對智能指針的基本用法進(jìn)行說明。

二、智能指針的基本用法

智能指針設(shè)計的初衷就是可以幫助我們管理堆上申請的內(nèi)存,可以理解為開發(fā)者只需要申請,而釋放交給智能指針。

目前 C++11 主要支持的智能指針為以下幾種

  • unique_ptr

  • shared_ptr

  • weak_ptr

2.1 unique_ptr

先上代碼

class?A { public:void?do_something()?{} };void?test_unique_ptr(bool?open) {std::unique_ptr<A>?a(new?A());a->do_something();if(open){//?不再需要手動釋放內(nèi)存return;}//?不再需要手動釋放內(nèi)存return; }

unique_ptr的核心特點(diǎn)就如它的名字一樣,它擁有對持有對象的唯一所有權(quán)。即兩個unique_ptr不能同時指向同一個對象。

那具體這個唯一所有權(quán)如何體現(xiàn)呢?

1、unique_ptr不能被復(fù)制到另外一個unique_ptr

2、unique_ptr所持有的對象只能通過轉(zhuǎn)移語義將所有權(quán)轉(zhuǎn)移到另外一個unique_ptr

std::unique_ptr<A>?a1(new?A()); std::unique_ptr<A>?a2?=?a1;//編譯報錯,不允許復(fù)制 std::unique_ptr<A>?a3?=?std::move(a1);//可以轉(zhuǎn)移所有權(quán),所有權(quán)轉(zhuǎn)義后a1不再擁有任何指針

智能指針有一個通用的規(guī)則,就是->表示用于調(diào)用指針原有的方法,而.則表示調(diào)用智能指針本身的方法。

unique_ptr本身擁有的方法主要包括:

1、get() 獲取其保存的原生指針,盡量不要使用

2、bool() 判斷是否擁有指針

3、release() 釋放所管理指針的所有權(quán),返回原生指針。但并不銷毀原生指針。

4、reset() 釋放并銷毀原生指針。如果參數(shù)為一個新指針,將管理這個新指針

std::unique_ptr<A>?a1(new?A()); A?*origin_a?=?a1.get();//盡量不要暴露原生指針 if(a1) {//?a1?擁有指針 }std::unique_ptr<A>?a2(a1.release());//常見用法,轉(zhuǎn)義擁有權(quán) a2.reset(new?A());//釋放并銷毀原有對象,持有一個新對象 a2.reset();//釋放并銷毀原有對象,等同于下面的寫法 a2?=?nullptr;//釋放并銷毀原有對象

2.2 shared_ptr

與unique_ptr的唯一所有權(quán)所不同的是,shared_ptr強(qiáng)調(diào)的是共享所有權(quán)。也就是說多個shared_ptr可以擁有同一個原生指針的所有權(quán)。

std::shared_ptr<A>?a1(new?A()); std::shared_ptr<A>?a2?=?a1;//編譯正常,允許所有權(quán)的共享

shared_ptr 是通過引用計數(shù)的方式管理指針,當(dāng)引用計數(shù)為 0 時會銷毀擁有的原生對象。

shared_ptr本身擁有的方法主要包括:

1、get() 獲取其保存的原生指針,盡量不要使用

2、bool() 判斷是否擁有指針

3、reset() 釋放并銷毀原生指針。如果參數(shù)為一個新指針,將管理這個新指針

4、unique() 如果引用計數(shù)為 1,則返回 true,否則返回 false

5、use_count() 返回引用計數(shù)的大小

std::shared_ptr<A>?a1(new?A()); std::shared_ptr<A>?a2?=?a1;//編譯正常,允許所有權(quán)的共享A?*origin_a?=?a1.get();//盡量不要暴露原生指針if(a1) {//?a1?擁有指針 }if(a1.unique()) {//?如果返回true,引用計數(shù)為1 }long?a1_use_count?=?a1.use_count();//引用計數(shù)數(shù)量

2.3 weak_ptr

weak_ptr 比較特殊,它主要是為了配合shared_ptr而存在的。就像它的名字一樣,它本身是一個弱指針,因?yàn)樗旧硎遣荒苤苯诱{(diào)用原生指針的方法的。如果想要使用原生指針的方法,需要將其先轉(zhuǎn)換為一個shared_ptr。那weak_ptr存在的意義到底是什么呢?

由于shared_ptr是通過引用計數(shù)來管理原生指針的,那么最大的問題就是循環(huán)引用(比如 a 對象持有 b 對象,b 對象持有 a 對象),這樣必然會導(dǎo)致內(nèi)存泄露。而weak_ptr不會增加引用計數(shù),因此將循環(huán)引用的一方修改為弱引用,可以避免內(nèi)存泄露。

weak_ptr可以通過一個shared_ptr創(chuàng)建。

std::shared_ptr<A>?a1(new?A()); std::weak_ptr<A>?weak_a1?=?a1;//不增加引用計數(shù)

weak_ptr本身擁有的方法主要包括:

1、expired() 判斷所指向的原生指針是否被釋放,如果被釋放了返回 true,否則返回 false

2、use_count() 返回原生指針的引用計數(shù)

3、lock() 返回 shared_ptr,如果原生指針沒有被釋放,則返回一個非空的 shared_ptr,否則返回一個空的 shared_ptr

4、reset() 將本身置空

std::shared_ptr<A>?a1(new?A()); std::weak_ptr<A>?weak_a1?=?a1;//不增加引用計數(shù)if(weak_a1.expired()) {//如果為true,weak_a1對應(yīng)的原生指針已經(jīng)被釋放了 }long?a1_use_count?=?weak_a1.use_count();//引用計數(shù)數(shù)量if(std::shared_ptr<A>?shared_a?=?weak_a1.lock()) {//此時可以通過shared_a進(jìn)行原生指針的方法調(diào)用 }weak_a1.reset();//將weak_a1置空

三、智能指針的最佳實(shí)踐

以上只是智能指針的基本用法,但是真正上手實(shí)踐的時候,卻發(fā)現(xiàn)程序在不經(jīng)意間崩潰了。踩過了幾次坑后,很多同學(xué)就罵罵咧咧的放棄了(什么辣雞東西)。因此想要用好智能指針還需要進(jìn)一步了解智能指針,甚至需要了解智能指針源碼實(shí)現(xiàn)。

這一節(jié)我們會基于基本用法,進(jìn)一步說明智能指針的實(shí)踐用法,一起馴服智能指針這頭野獸。

3.1 智能指針如何選擇

在介紹指針如何選擇之前,我們先回顧一下這幾個指針的特點(diǎn)

1、unique_ptr獨(dú)占對象的所有權(quán),由于沒有引用計數(shù),因此性能較好

2、shared_ptr共享對象的所有權(quán),但性能略差

3、weak_ptr配合shared_ptr,解決循環(huán)引用的問題

由于性能問題,那么可以粗暴的理解:優(yōu)先使用unique_ptr。但由于unique_ptr不能進(jìn)行復(fù)制,因此部分場景下不能使用的。

3.1.1 unique_ptr 的使用場景

unique_ptr一般在不需要多個指向同一個對象的指針時使用。但這個條件本身就很難判斷,在我看來可以簡單的理解:這個對象在對象或方法內(nèi)部使用時優(yōu)先使用unique_ptr。

1、對象內(nèi)部使用

class?TestUnique { private:std::unique_ptr<A>?a_?=?std::unique_ptr<A>(new?A()); public:void?process1(){a_->do_something();}void?process2(){a_->do_something();}~TestUnique(){//此處不再需要手動刪除a_} };

2、方法內(nèi)部使用

void?test_unique_ptr() {std::unique_ptr<A>?a(new?A());a->do_something(); }
3.1.2 shared_ptr 的使用場景及最佳實(shí)踐

shared_ptr一般在需要多個執(zhí)行同一個對象的指針使用。在我看來可以簡單的理解:這個對象需要被多個 Class 同時使用的時候。

class?B { private:std::shared_ptr<A>?a_;public:B(std::shared_ptr<A>&?a):?a_(a)?{} };class?C { private:std::shared_ptr<A>?a_;public:C(std::shared_ptr<A>&?a):?a_(a)?{} };std::shared_ptr<B>?b_; std::shared_ptr<C>?c_;void?test_A_B_C() {std::shared_ptr<A>?a?=?std::make_shared<A>();b_?=?std::make_shared<B>(a);c_?=?std::make_shared<C>(a); }

在上面的代碼中需要注意,我們使用std::make_shared代替new的方式創(chuàng)建shared_ptr。

因?yàn)槭褂胣ew的方式創(chuàng)建shared_ptr會導(dǎo)致出現(xiàn)兩次內(nèi)存申請,而std::make_shared在內(nèi)部實(shí)現(xiàn)時只會申請一個內(nèi)存。因此建議后續(xù)均使用std::make_shared。

如果A想要調(diào)用B和C的方法怎么辦呢?可否在A中定義B和C的shared_ptr呢?答案是不可以,這樣會產(chǎn)生循環(huán)引用,導(dǎo)致內(nèi)存泄露。

此時就需要weak_ptr出場了。

class?A { private:std::weak_ptr<B>?b_;std::weak_ptr<C>?c_; public:void?do_something()?{}void?set_B_C(const?std::shared_ptr<B>&?b,?const?std::shared_ptr<C>&?c){b_?=?b;c_?=?c;} };a->set_B_C(b_,?c_);

如果想要在A內(nèi)部將當(dāng)前對象的指針共享給其他對象,需要怎么處理呢?

class?D { private:std::shared_ptr<A>?a_;public:std::shared_ptr<A>&?a):?a_(a)?{} };class?A { //上述代碼省略public:void?new_D(){//錯誤方式,用this指針重新構(gòu)造shared_ptr,將導(dǎo)致二次釋放當(dāng)前對象std::shared_ptr<A>?this_shared_ptr1(this);std::unique_ptr<D>?d1(new?D(this_shared_ptr1));} };

如果采用this指針重新構(gòu)造shared_ptr是肯定不行的,因?yàn)橹匦聞?chuàng)建的shared_ptr與當(dāng)前對象的shared_ptr沒有關(guān)系,沒有增加當(dāng)前對象的引用計數(shù)。這將導(dǎo)致任何一個shared_ptr計數(shù)為 0 時提前釋放了對象,后續(xù)操作這個釋放的對象都會導(dǎo)致程序異常。

此時就需要引入shared_from_this。對象繼承了enable_shared_from_this后,可以通過shared_from_this()獲取當(dāng)前對象的shared_ptr指針。

class?A:?public?std::enable_shared_from_this<A> { //上述代碼省略public:void?new_D(){//錯誤方式,用this指針重新構(gòu)造shared_ptr,將導(dǎo)致二次釋放當(dāng)前對象std::shared_ptr<A>?this_shared_ptr1(this);std::unique_ptr<D>?d1(new?D(this_shared_ptr1));//正確方式std::shared_ptr<A>?this_shared_ptr2?=?shared_from_this();std::unique_ptr<D>?d2(new?D(this_shared_ptr2));} };

3.2 智能指針的錯誤用法

智能指針的使用時有較多常見的錯誤用法,可能會導(dǎo)致程序異常。下面我會列舉這些錯誤用法,開發(fā)時需要避免。

1、使用智能指針托管的對象,盡量不要在再使用原生指針

很多開發(fā)同學(xué)(包括我在內(nèi))在最開始使用智能指針的時候,對同一個對象會混用智能指針和原生指針,導(dǎo)致程序異常。

void?incorrect_smart_pointer1() {A?*a=?new?A();std::unique_ptr<A>?unique_ptr_a(a);//?此處將導(dǎo)致對象的二次釋放delete?a; }

2、不要把一個原生指針交給多個智能指針管理

如果將一個原生指針交個多個智能指針,這些智能指針釋放對象時會產(chǎn)生對象的多次銷毀

void?incorrect_smart_pointer2() {A?*a=?new?A();std::unique_ptr<A>?unique_ptr_a1(a);std::unique_ptr<A>?unique_ptr_a2(a);//?此處將導(dǎo)致對象的二次釋放 }

3、盡量不要使用 get()獲取原生指針

void?incorrect_smart_pointer3() {std::shared_ptr<A>?shared_ptr_a1?=?std::make_shared<A>();A?*a=?shared_ptr_a1.get();std::shared_ptr<A>?shared_ptr_a2(a);//?此處將導(dǎo)致對象的二次釋放delete?a;//?此處也將導(dǎo)致對象的二次釋放 }

4、不要將 this 指針直接托管智能指針

class?E {void?use_this(){//錯誤方式,用this指針重新構(gòu)造shared_ptr,將導(dǎo)致二次釋放當(dāng)前對象std::shared_ptr<E>?this_shared_ptr1(this);} };std::shared_ptr<E>?e?=?std::make_shared<E>();

5、智能指針只能管理堆對象,不能管理?xiàng)I蠈ο?/p>

棧上對象本身在出棧時就會被自動銷毀,如果將其指針交給智能指針,會造成對象的二次銷毀

void?incorrect_smart_pointer5() {int?int_num?=?3;std::unique_ptr<int>?int_unique_ptr(&amp;int_num); }

3.3 解決多線程下對象析構(gòu)問題

有了智能指針之后,我們就可以使用智能指針解決多線程下的對象析構(gòu)問題。

我們使用shared_ptr管理ReportClass。并將 weak_ptr傳給子線程,子線程會判斷外部的ReportClass是否已經(jīng)被銷毀,如果沒有被銷毀會通過weak_ptr換取shared_ptr,否則線程退出。解決了外部對象銷毀,內(nèi)部線程使用外部對象的野指針的問題。

//?日志上報Class class?ReportClass:?public?std::enable_shared_from_this<ReportClass> {//...private:static?void?workThread(std::weak_ptr<ReportClass>?weak_report_ptr);private:static?std::shared_ptr<ReportClass>?instance_;static?std::mutex?static_mutex_;public:static?std::shared_ptr<ReportClass>?GetInstance();static?void?ReleaseInstance(); };std::mutex?ReportClass::static_mutex_; std::shared_ptr<ReportClass>?ReportClass::instance_;std::shared_ptr<ReportClass>?ReportClass::GetInstance() {//?單例簡單實(shí)現(xiàn),非本文重點(diǎn)std::lock_guard<std::mutex>?lock(static_mutex_);if?(!instance_)?{instance_?=?std::shared_ptr<ReportClass>(new?ReportClass());instance_->addWorkThread();}return?instance_; }void?ReportClass::ReleaseInstance() {std::lock_guard<std::mutex>?lock(static_mutex_);if(instance_){instance_.reset();} }//?輪詢上報線程 void?ReportClass::workThread(std::weak_ptr<ReportClass>?weak_report_ptr) {while(true){std::shared_ptr<ReportClass>?shared_report_ptr?=?weak_report_ptr.lock();if(!shared_report_ptr){return;}std::unique_lock<std::mutex>(shared_report_ptr->mutex_);if(shared_report_ptr->count_?>?0){shared_report_ptr->count_--;}usleep(1000*1000);} }//?創(chuàng)建任務(wù)線程 void?ReportClass::addWorkThread() {std::weak_ptr<ReportClass>?weak_report_ptr?=?shared_from_this();std::thread?work_thread(workThread,?weak_report_ptr);work_thread.detach(); }//?外部調(diào)用 void?ReportClass::pushEvent(std::string?event) {std::unique_lock<std::mutex>?lock(mutex_);this->count_++; }

并且在多個線程使用的時候,由于采用shared_ptr管理,因此只要有shared_ptr持有對象,就不會銷毀對象,因此不會出現(xiàn)多個線程使用時對象被析構(gòu)的情況。只有該對象的所有shared_ptr都被銷毀的時候,對象的內(nèi)存才會被釋放,保證的對象析構(gòu)的安全。

四、智能指針源碼解析

在介紹智能指針源碼前,需要明確的是,智能指針本身是一個棧上分配的對象。根據(jù)棧上分配的特性,在離開作用域后,會自動調(diào)用其析構(gòu)方法。智能指針根據(jù)這個特性實(shí)現(xiàn)了對象內(nèi)存的管理和自動釋放。

本文所分析的智能指針源碼基于 Android ndk-16b 中 llvm-libc++的 memory 文件。

4.1 unique_ptr

先看下 unique_ptr的聲明。unique_ptr有兩個模板參數(shù),分別為_Tp和_Dp。

  • _Tp表示原生指針的類型。

  • _Dp則表示析構(gòu)器,開發(fā)者可以自定義指針銷毀的代碼。其擁有一個默認(rèn)值default_delete<_Tp>,其實(shí)就是標(biāo)準(zhǔn)的delete函數(shù)。

函數(shù)聲明中typename __pointer_type<_Tp, deleter_type>::type可以簡單理解為_Tp*,即原生指針類型。

template <class _Tp, class _Dp = default_delete<_Tp> > class _LIBCPP_TEMPLATE_VIS unique_ptr { public:typedef _Tp element_type;typedef _Dp deleter_type;typedef typename __pointer_type<_Tp, deleter_type>::type pointer;//... }

unique_ptr中唯一的數(shù)據(jù)成員就是原生指針和析構(gòu)器的 pair。

private:__compressed_pair<pointer,?deleter_type>?__ptr_;

下面看下unique_ptr的構(gòu)造函數(shù)。

template?<class?_Tp,?class?_Dp?=?default_delete<_Tp>?> class?_LIBCPP_TEMPLATE_VIS?unique_ptr?{public://?默認(rèn)構(gòu)造函數(shù),用pointer的默認(rèn)構(gòu)造函數(shù)初始化__ptr_constexpr?unique_ptr()?noexcept?:?__ptr_(pointer())?{}//?空指針的構(gòu)造函數(shù),同上constexpr?unique_ptr(nullptr_t)?noexcept?:?__ptr_(pointer())?{}//?原生指針的構(gòu)造函數(shù),用原生指針初始化__ptr_explicit?unique_ptr(pointer?__p)?noexcept?:?__ptr_(__p)?{}//?原生指針和析構(gòu)器的構(gòu)造函數(shù),用這兩個參數(shù)初始化__ptr_,當(dāng)前析構(gòu)器為左值引用unique_ptr(pointer?__p,?_LValRefType<_Dummy>?__d)?noexcept:?__ptr_(__p,?__d)?{}//?原生指針和析構(gòu)器的構(gòu)造函數(shù),析構(gòu)器使用轉(zhuǎn)移語義進(jìn)行轉(zhuǎn)移unique_ptr(pointer?__p,?_GoodRValRefType<_Dummy>?__d)?noexcept:?__ptr_(__p,?_VSTD::move(__d))?{static_assert(!is_reference<deleter_type>::value,"rvalue?deleter?bound?to?reference");}//?移動構(gòu)造函數(shù),取出原有unique_ptr的指針和析構(gòu)器進(jìn)行構(gòu)造unique_ptr(unique_ptr&&?__u)?noexcept:?__ptr_(__u.release(),?_VSTD::forward<deleter_type>(__u.get_deleter()))?{}//?移動賦值函數(shù),取出原有unique_ptr的指針和析構(gòu)器進(jìn)行構(gòu)造unique_ptr&?operator=(unique_ptr&&?__u)?_NOEXCEPT?{reset(__u.release());__ptr_.second()?=?_VSTD::forward<deleter_type>(__u.get_deleter());return?*this;}}

再看下unique_ptr幾個常用函數(shù)的實(shí)現(xiàn)。

template?<class?_Tp,?class?_Dp?=?default_delete<_Tp>?> class?_LIBCPP_TEMPLATE_VIS?unique_ptr?{//?返回原生指針 pointer?get()?const?_NOEXCEPT?{return?__ptr_.first(); }//?判斷原生指針是否為空 _LIBCPP_EXPLICIT?operator?bool()?const?_NOEXCEPT?{return?__ptr_.first()?!=?nullptr; }//?將__ptr置空,并返回原有的指針 pointer?release()?_NOEXCEPT?{pointer?__t?=?__ptr_.first();__ptr_.first()?=?pointer();return?__t; }//?重置原有的指針為新的指針,如果原有指針不為空,對原有指針?biāo)笇ο筮M(jìn)行銷毀 void?reset(pointer?__p?=?pointer())?_NOEXCEPT?{pointer?__tmp?=?__ptr_.first();__ptr_.first()?=?__p;if?(__tmp)__ptr_.second()(__tmp); } }

再看下unique_ptr指針特性的兩個方法。

//?返回原生指針的引用 typename?add_lvalue_reference<_Tp>::type operator*()?const?{return?*__ptr_.first(); } //?返回原生指針 pointer?operator->()?const?_NOEXCEPT?{return?__ptr_.first(); }

最后再看下unique_ptr的析構(gòu)函數(shù)。

//?通過reset()方法進(jìn)行對象的銷毀 ~unique_ptr()?{?reset();?}

4.2 shared_ptr

shared_ptr 與unique_ptr最核心的區(qū)別就是比unique_ptr多了一個引用計數(shù),并由于引用計數(shù)的加入,可以支持拷貝。

先看下shared_ptr的聲明。shared_ptr主要有兩個成員變量,一個是原生指針,一個是控制塊的指針,用來存儲這個原生指針的shared_ptr和weak_ptr的數(shù)量。

template<class?_Tp> class?shared_ptr { public:typedef?_Tp?element_type;private:element_type*??????__ptr_;__shared_weak_count*?__cntrl_;//... }

我們重點(diǎn)看下__shared_weak_count的定義。

//?共享計數(shù)類 class?__shared_count {__shared_count(const?__shared_count&);__shared_count&?operator=(const?__shared_count&);protected://?共享計數(shù)long?__shared_owners_;virtual?~__shared_count(); private://?引用計數(shù)變?yōu)?的回調(diào),一般是進(jìn)行內(nèi)存釋放virtual?void?__on_zero_shared()?_NOEXCEPT?=?0;public://?構(gòu)造函數(shù),需要注意內(nèi)部存儲的引用計數(shù)是從0開始,外部看到的引用計數(shù)其實(shí)為1explicit?__shared_count(long?__refs?=?0)?_NOEXCEPT:?__shared_owners_(__refs)?{}//?增加共享計數(shù)void?__add_shared()?_NOEXCEPT?{__libcpp_atomic_refcount_increment(__shared_owners_);}//?釋放共享計數(shù),如果共享計數(shù)為0(內(nèi)部為-1),則調(diào)用__on_zero_shared進(jìn)行內(nèi)存釋放bool?__release_shared()?_NOEXCEPT?{if?(__libcpp_atomic_refcount_decrement(__shared_owners_)?==?-1)?{__on_zero_shared();return?true;}return?false;}//?返回引用計數(shù),需要對內(nèi)部存儲的引用計數(shù)+1處理long?use_count()?const?_NOEXCEPT?{return?__libcpp_relaxed_load(&amp;__shared_owners_)?+?1;} };class?__shared_weak_count:?private?__shared_count {//?weak?ptr計數(shù)long?__shared_weak_owners_;public://?內(nèi)部共享計數(shù)和weak計數(shù)都為0explicit?__shared_weak_count(long?__refs?=?0)?_NOEXCEPT:?__shared_count(__refs),__shared_weak_owners_(__refs)?{} protected:virtual?~__shared_weak_count();public://?調(diào)用通過父類的__add_shared,增加共享引用計數(shù)void?__add_shared()?_NOEXCEPT?{__shared_count::__add_shared();}//?增加weak引用計數(shù)void?__add_weak()?_NOEXCEPT?{__libcpp_atomic_refcount_increment(__shared_weak_owners_);}//?調(diào)用父類的__release_shared,如果釋放了原生指針的內(nèi)存,還需要調(diào)用__release_weak,因?yàn)閮?nèi)部weak計數(shù)默認(rèn)為0void?__release_shared()?_NOEXCEPT?{if?(__shared_count::__release_shared())__release_weak();}//?weak引用計數(shù)減1void?__release_weak()?_NOEXCEPT;//?獲取共享計數(shù)long?use_count()?const?_NOEXCEPT?{return?__shared_count::use_count();}__shared_weak_count*?lock()?_NOEXCEPT;private://?weak計數(shù)為0的處理virtual?void?__on_zero_shared_weak()?_NOEXCEPT?=?0; };

其實(shí)__shared_weak_count也是虛類,具體使用的是__shared_ptr_pointer。__shared_ptr_pointer中有一個成員變量__data_,用于存儲原生指針、析構(gòu)器、分配器。__shared_ptr_pointer繼承了__shared_weak_count,因此它就主要負(fù)責(zé)內(nèi)存的分配、銷毀,引用計數(shù)。

class?__shared_ptr_pointer:?public?__shared_weak_count {__compressed_pair<__compressed_pair<_Tp,?_Dp>,?_Alloc>?__data_; public:_LIBCPP_INLINE_VISIBILITY__shared_ptr_pointer(_Tp?__p,?_Dp?__d,?_Alloc?__a):??__data_(__compressed_pair<_Tp,?_Dp>(__p,?_VSTD::move(__d)),?_VSTD::move(__a))?{}#ifndef?_LIBCPP_NO_RTTIvirtual?const?void*?__get_deleter(const?type_info&)?const?_NOEXCEPT; #endifprivate:virtual?void?__on_zero_shared()?_NOEXCEPT;virtual?void?__on_zero_shared_weak()?_NOEXCEPT; };

了解了引用計數(shù)的基本原理后,再看下shared_ptr的實(shí)現(xiàn)。

//?使用原生指針構(gòu)造shared_ptr時,會構(gòu)建__shared_ptr_pointer的控制塊 shared_ptr<_Tp>::shared_ptr(_Yp*?__p,typename?enable_if<is_convertible<_Yp*,?element_type*>::value,?__nat>::type):?__ptr_(__p) {unique_ptr<_Yp>?__hold(__p);typedef?typename?__shared_ptr_default_allocator<_Yp>::type?_AllocT;typedef?__shared_ptr_pointer<_Yp*,?default_delete<_Yp>,?_AllocT?>?_CntrlBlk;__cntrl_?=?new?_CntrlBlk(__p,?default_delete<_Yp>(),?_AllocT());__hold.release();__enable_weak_this(__p,?__p); }//?如果進(jìn)行shared_ptr的拷貝,會增加引用計數(shù) template<class?_Tp> inline shared_ptr<_Tp>::shared_ptr(const?shared_ptr&?__r)?_NOEXCEPT:?__ptr_(__r.__ptr_),__cntrl_(__r.__cntrl_) {if?(__cntrl_)__cntrl_->__add_shared(); }//?銷毀shared_ptr時,會使共享引用計數(shù)減1,如果減到0會銷毀內(nèi)存 template<class?_Tp> shared_ptr<_Tp>::~shared_ptr() {if?(__cntrl_)__cntrl_->__release_shared(); }

4.3 weak_ptr

了解完shared_ptr,weak_ptr也就比較簡單了。weak_ptr也包括兩個對象,一個是原生指針,一個是控制塊。雖然weak_ptr內(nèi)存儲了原生指針,不過由于未實(shí)現(xiàn)operator->因此不能直接使用。

class?_LIBCPP_TEMPLATE_VIS?weak_ptr { public:typedef?_Tp?element_type; private:element_type*????????__ptr_;__shared_weak_count*?__cntrl_;}//?通過shared_ptr構(gòu)造weak_ptr。會將shared_ptr的成員變量地址進(jìn)行復(fù)制。增加weak引用計數(shù) weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp>?const&amp;?__r,typename?enable_if<is_convertible<_Yp*,?_Tp*>::value,?__nat*>::type)_NOEXCEPT:?__ptr_(__r.__ptr_),__cntrl_(__r.__cntrl_) {if?(__cntrl_)__cntrl_->__add_weak(); }//?weak_ptr析構(gòu)器 template<class?_Tp> weak_ptr<_Tp>::~weak_ptr() {if?(__cntrl_)__cntrl_->__release_weak(); }

最近熱文:

淺談 K8s 網(wǎng)絡(luò)模型CNI協(xié)議

提速 30%!騰訊TQUIC 網(wǎng)絡(luò)傳輸協(xié)議

大牛書單 | 消息隊(duì)列方向的好書

總結(jié)

以上是生活随笔為你收集整理的C++ 智能指针最佳实践源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

日韩电影在线看 | 免费男女羞羞的视频网站中文字幕 | 久久黄色小说视频 | 成人久久久久久久久久 | 免费久草视频 | 国产一级高清 | 婷婷色影院 | 日韩网站中文字幕 | 亚洲精品国产精品国产 | 国产精品不卡在线观看 | 久久夜夜夜 | 99精品视频在线看 | 特级黄色一级 | 97成人精品视频在线播放 | 日本九九视频 | 天天干国产 | 亚洲精品乱码久久久久v最新版 | 婷婷色中文字幕 | 黄色成品视频 | 亚洲成av人片一区二区梦乃 | 日韩专区av| 亚洲天堂精品 | 国产原创在线观看 | 日韩欧美在线综合网 | av中文字幕在线免费观看 | 久久精品亚洲国产 | 在线观看a视频 | 国产亚洲欧美在线视频 | av黄色免费看 | 日韩高清在线一区二区三区 | 免费久久久久久久 | 午夜精品三区 | 亚洲精品高清一区二区三区四区 | 免费福利视频导航 | 黄色毛片一级 | av电影在线播放 | 久久久受www免费人成 | 一区二区精品在线 | 国产精品理论片在线观看 | 国产精品国产三级国产aⅴ入口 | 99激情网 | 亚洲精品乱码久久久久v最新版 | 成人小视频在线观看免费 | 午夜久久美女 | 欧美一级电影片 | 韩国av一区二区 | 中文视频在线看 | 欧美极度另类性三渗透 | 天天躁日日躁狠狠 | 亚洲人成网站精品片在线观看 | 亚洲国产中文字幕在线观看 | 日韩在线高清 | 亚洲综合在线五月天 | 2023国产精品自产拍在线观看 | 国产又粗又猛又黄又爽的视频 | 国产精品国产亚洲精品看不卡15 | 97在线观看免费观看高清 | 国产在线不卡一区 | 日精品在线观看 | av国产在线观看 | 91麻豆精品国产自产在线游戏 | 夜夜操天天干, | 插久久| 成人av地址| 亚洲天堂网在线播放 | 亚洲欧美怡红院 | 国产一区在线免费 | 久久国产精品久久精品国产演员表 | 亚洲精品播放 | 东方av在线免费观看 | 久草视频精品 | 国产黄色av网站 | 久久综合婷婷国产二区高清 | 精品亚洲男同gayvideo网站 | av中文字幕网站 | 国产无遮挡又黄又爽在线观看 | 日韩一级电影在线观看 | 天天操天天添天天吹 | 成年人黄色大片在线 | 国产精品美女久久久免费 | 麻豆视频免费在线播放 | 色99在线 | av高清一区二区三区 | 国内久久久| 伊人资源站 | 色婷婷啪啪免费在线电影观看 | 激情五月婷婷激情 | 99超碰在线播放 | 日韩中文字幕a | 99热精品国产一区二区在线观看 | 天天干com | 精品国产一区二区三区久久久蜜月 | 波多野结衣在线观看视频 | 韩国在线一区 | 亚洲欧洲国产视频 | 欧美一级视频在线观看 | 日日添夜夜添 | 成人一级黄色片 | 国产精品久久久久四虎 | 亚洲国产理论片 | 色多多污污 | 岛国大片免费视频 | 亚洲年轻女教师毛茸茸 | 美女在线黄 | 国产高清视频在线播放 | 免费亚洲成人 | 亚洲成人家庭影院 | 国产视频18| 五月婷婷一区二区三区 | 99色在线观看视频 | 久久精品电影院 | 一区二区精品视频 | 美女黄频免费 | 91精品国产九九九久久久亚洲 | 国产高清在线精品 | 韩日精品中文字幕 | 成人手机在线视频 | 国产黄网在线 | 五月婷婷狠狠 | 国产在线观看不卡 | 日韩久久久久久久久久 | 日韩欧美高清一区二区 | 成人av在线播放网站 | 日韩专区在线观看 | 97天天综合网 | 亚洲午夜久久久久久久久电影网 | 国产又粗又猛又色 | 久久免费av | 婷婷在线五月 | 欧美日韩另类在线 | 9999亚洲 | 欧美男男激情videos | 亚洲视频在线看 | 欧美一二三区在线播放 | 中文字幕在线网 | 免费看wwwwwwwwwww的视频 久久久久久99精品 91中文字幕视频 | 久草在线综合 | 在线色资源| 欧美一区在线观看视频 | 免费在线观看av | 极品久久久久久久 | 日韩色一区二区三区 | 天天玩天天操天天射 | 国产97在线观看 | 综合色狠狠 | 奇米影视8888在线观看大全免费 | 久久中国精品 | 欧美九九视频 | 97人人爽| 国产香蕉视频在线观看 | 国产精品久久久久免费 | 日韩精品影视 | 成人黄色在线电影 | 久久激情五月丁香伊人 | 中文字幕在线看视频 | 久久精品人人做人人综合老师 | 九九九九精品九九九九 | 久久久久亚洲a | 久久激情综合 | 免费视频 三区 | 麻豆影视在线播放 | www日 | 久草在线免费资源 | 五月婷婷综合色拍 | 91麻豆精品国产91久久久更新时间 | 国产高清免费 | 久久久久久久久久久久电影 | 2018亚洲男人天堂 | 久久99亚洲热视 | 日韩亚洲在线视频 | 欧美综合国产 | av软件在线观看 | 91精品国产综合久久福利 | 黄色小网站在线观看 | 国产 日韩 欧美 中文 在线播放 | 国产精久久久 | 青青河边草免费直播 | 中文视频在线播放 | 久久系列| 日韩色爱 | 91麻豆精品91久久久久同性 | 国产无套精品久久久久久 | 国产又黄又爽又猛视频日本 | 在线中文字母电影观看 | 999久久久免费精品国产 | 91精品久久久久久久久久久久久 | 久久精品激情 | 亚洲精品高清在线观看 | 国产成人三级一区二区在线观看一 | 极品久久久| 中文字幕av专区 | 激情小说久久 | 亚洲精品美女在线 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 91精品伦理 | 夜夜看av| 亚洲精品午夜一区人人爽 | 高清久久久 | 91在线免费观看国产 | 国模一区二区三区四区 | 日韩在线视频观看免费 | 天天看天天干天天操 | 国产在线欧美日韩 | 日本精品中文字幕在线观看 | 色综合欧洲| 99精品国产免费久久久久久下载 | 日韩一级成人av | 亚洲一区二区精品 | 精品国产免费观看 | 超碰在线中文字幕 | 国产一区二区不卡在线 | 亚洲视频中文 | 特及黄色片 | 一区二区三区日韩在线观看 | 超碰在线99| 亚洲视频在线免费观看 | 国产a级免费 | 亚洲精品国偷自产在线99热 | 91看片看淫黄大片 | 日韩三级免费 | 五月婷婷六月丁香激情 | 日本一区二区三区免费观看 | 97人人爽人人 | 欧美日韩在线视频一区 | 中文字幕在线播放第一页 | 日韩av电影免费观看 | 国产91在线 | 美洲 | 午夜资源站 | 最近最新最好看中文视频 | 亚洲国内精品 | 在线中文字幕观看 | 日韩精品一区二区免费视频 | 国产精品99久久久久久武松影视 | 欧美黄色特级片 | av在线一二三区 | www国产亚洲 | 国产视频在线播放 | 国产69精品久久99不卡的观看体验 | 国产在线观看污片 | 国产午夜一级毛片 | 在线免费观看羞羞视频 | 免费高清无人区完整版 | 国产高清不卡一区二区三区 | 五月天综合在线 | 精品免费视频123区 午夜久久成人 | 日韩在线观看视频中文字幕 | 亚洲色图 校园春色 | 少妇超碰在线 | 中文字幕黄色网址 | 久久精品一区二区三区视频 | 一本一本久久a久久精品综合 | 丁香五月网久久综合 | 国产黄色一级大片 | 久久久18| 欧美va在线观看 | 欧美色噜噜噜 | 天天色影院 | 精品一二三区视频 | 日批在线观看 | 天天色官网| 在线观看91av | 免费看片网址 | 日韩在线观看免费 | 久久与婷婷 | 国产精品3区 | 九九久久久久久久久激情 | 成人性生爱a∨ | 伊人手机在线 | 黄色在线视频网址 | 久久论理 | 天天做综合网 | 黄色三级在线观看 | 亚洲精品一区二区18漫画 | 中文字幕av日韩 | 国产精品久久毛片 | 亚洲欧洲久久久 | 国产精品久久久久久欧美 | 国产日产在线观看 | 国产中文字幕在线 | 夜夜操天天干 | 天天摸天天舔 | 伊人婷婷| 中文字幕在线乱 | 91看成人| 国产色在线视频 | 黄色亚洲 | 久久国产电影 | 四虎欧美 | 日本在线成人 | 二区视频在线观看 | 国产精品自拍在线 | 欧美日韩午夜在线 | 亚洲3级| 国产视频一区二区在线观看 | 国产高清不卡一区二区三区 | 91麻豆视频网站 | 国产视频在线观看一区 | 999国内精品永久免费视频 | 日本久久久影视 | 亚洲精品福利在线观看 | 精品九九九九 | 国产伦理一区二区 | 亚洲精品欧洲精品 | 91喷水| 黄色av一级片 | 国产精品21区 | 国产亚洲精品久久久久秋 | 婷婷六月天综合 | 久久国产香蕉视频 | 欧美极品一区二区三区 | 久久精品视频在线免费观看 | 777视频在线观看 | 国产一区在线播放 | www.五月激情.com | 亚洲最大色 | 狠狠网亚洲精品 | 精品久久久久一区二区国产 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 丁香五婷| 久久久久久久久免费 | 色噜噜日韩精品一区二区三区视频 | 日韩成人中文字幕 | 久久99精品国产麻豆宅宅 | 亚洲播播 | 激情综合色图 | 日韩免费大片 | 久久久久亚洲精品 | 99精品欧美一区二区三区黑人哦 | 久久人人爽人人人人片 | 中文字幕亚洲在线观看 | 男女男视频 | 99免费观看视频 | 中文字幕在线看视频 | 日韩欧美大片免费观看 | www.福利 | 992tv在线成人免费观看 | 日本在线观看一区二区三区 | 国产99久久久国产精品免费看 | 久久久鲁 | 成人sm另类专区 | 国产99久久久国产精品免费二区 | 欧美极品少妇xbxb性爽爽视频 | 日韩精品久久久久久久电影竹菊 | 2024av| 亚洲丝袜一区二区 | 激情视频免费在线观看 | 成人黄色在线电影 | 怡春院av| 丁香六月av| 四虎国产| 国产精品一区二区三区四区在线观看 | 色悠悠久久综合 | 国产精品都在这里 | 婷婷丁香狠狠爱 | 久久久999免费视频 日韩网站在线 | 亚洲一区日韩精品 | 免费在线激情电影 | 一区二区视频在线免费观看 | 国内精品视频久久 | 91精品久久久久久久久 | 欧美精品国产精品 | 超碰九九 | 一区二区三区精品在线 | 久久综合国产伦精品免费 | 一区二区三区污 | 在线视频观看成人 | 日本一区二区三区免费观看 | 日本天天色 | 91黄色小网站 | 成人全视频免费观看在线看 | 精品久久久久久久久久久久久 | 在线黄色免费 | 久久综合中文字幕 | 黄色www在线观看 | 中日韩欧美精彩视频 | 国产精品亚 | 久久久久久97三级 | 中文字幕乱码亚洲精品一区 | 久久午夜羞羞影院 | 国产精品久久久久久久久久直播 | 中文永久字幕 | 狠狠久久综合 | 欧美午夜a | 黄色免费网站大全 | 天天色天天操综合网 | 在线有码中文字幕 | 精品专区一区二区 | 九九九九精品 | 国产九九九精品视频 | 亚洲视频aaa| 久草a在线| 国产日韩精品一区二区在线观看播放 | 91大神免费视频 | 中文字幕在线观看第二页 | 在线看片日韩 | 中文字幕国语官网在线视频 | 久久久精品午夜 | 久热色超碰 | 国产精品一区久久久久 | 国产中文字幕在线 | 九九热精品在线 | 久久天天躁狠狠躁夜夜不卡公司 | 成年人免费av | 国产精品一区二区三区在线播放 | 最近免费中文字幕大全高清10 | 中文字幕在线观看网站 | 久久精品一区二 | 天天操天天干天天操天天干 | 国产成人精品久久久久 | 成人手机在线视频 | 91中文字幕在线播放 | bbbbb女女女女女bbbbb国产 | 欧美影片| 久久精品国产亚洲精品 | 国产五十路毛片 | 国产xxxxx在线观看 | 国内精品中文字幕 | 午夜久久久久久久久久久 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 99久久99视频 | 国产女人40精品一区毛片视频 | 99色99| 亚洲成人动漫在线观看 | 精品国产理论 | 亚洲在线精品视频 | 九九视频这里只有精品 | 九九九九精品九九九九 | 免费日韩av电影 | 日本在线中文在线 | 中文字幕成人在线 | 国产超碰在线观看 | 久要激情网 | 2023亚洲精品国偷拍自产在线 | 亚洲va天堂va欧美ⅴa在线 | 免费观看一级特黄欧美大片 | 天天干天天射天天插 | 色综合久久五月天 | 色五月激情五月 | 久久久国际精品 | 欧美性生活久久 | 亚洲黄色成人av | 4hu视频 | 91cn国产在线| 国产在线999 | 一区二区三区国产欧美 | 丁香六月网 | 中文字幕欧美日韩va免费视频 | 欧美三人交 | 天天碰天天操视频 | 久久99精品久久只有精品 | 成人av免费播放 | 97天天干| 国产香蕉在线 | 亚洲精品久久久久久久不卡四虎 | 一区二区三区视频在线 | 日日夜夜精品网站 | 97视频免费观看2区 亚洲视屏 | 毛片一区二区 | 国产成人精品一区二区三区 | 亚洲精品乱码白浆高清久久久久久 | 精品国偷自产在线 | 六月丁香伊人 | 亚洲欧洲美洲av | 黄色网www | 麻豆成人小视频 | 日韩性xxx| 色噜噜在线观看视频 | 最近更新中文字幕 | 四虎在线免费观看视频 | 精品视频国产 | 国产黄色片免费 | 手机看国产毛片 | 久久久久久久久久久国产精品 | 久久久久福利视频 | 久草在线视频新 | 99久久99视频只有精品 | 欧美另类性 | 在线看v片 | 色婷婷国产| 国产精品一区二区免费 | 在线免费视频a | 五月天丁香 | 超碰在线成人 | 久久久久伦理电影 | 日韩精品免费在线视频 | 久久久精品一区二区 | 免费日韩电影 | 美女视频黄频 | 黄色av在| 久久久久久久久久久精 | 久久视精品 | 国产精品福利午夜在线观看 | 亚洲精选在线 | 天天干,天天射,天天操,天天摸 | 欧美 日韩 国产 中文字幕 | 国产精品视频全国免费观看 | 亚洲天堂网视频在线观看 | 亚洲精品99久久久久久 | 亚洲精品久久久久久中文传媒 | 久久理论视频 | 黄色电影在线免费观看 | 国产 欧美 在线 | 久草免费手机视频 | 91麻豆精品国产91久久久久久久久 | 在线观看视频免费大全 | 狠狠干天天色 | 亚洲精品视频在 | 99久久精品免费看 | 五月综合 | 日韩av一区二区在线影视 | 亚洲成人xxx| 9免费视频| 久久亚洲在线 | 国产伦精品一区二区三区无广告 | 色的网站在线观看 | 在线观看免费中文字幕 | 成人不用播放器 | 国产精品 国产精品 | 久久av在线 | 欧美午夜寂寞影院 | 狠狠狠干| 99综合影院在线 | 国产又黄又爽又猛视频日本 | 激情电影影院 | 亚洲精品久久在线 | 国产aa免费视频 | 探花视频在线版播放免费观看 | 色噜噜在线观看视频 | 免费在线观看国产精品 | 日本精品视频一区二区 | 在线中文字幕播放 | 久久国语露脸国产精品电影 | 2018精品视频| 久久久精品网站 | 一级特黄aaa大片在线观看 | 国产日产精品一区二区三区四区 | 黄色软件在线观看视频 | 人人干狠狠操 | 永久黄网站色视频免费观看w | 久久久久久久亚洲精品 | 337p日本欧洲亚洲大胆裸体艺术 | 六月丁香激情网 | 久草在线手机观看 | 99中文字幕在线观看 | 国产成人精品在线播放 | 色婷婷免费视频 | 亚洲在线高清 | 黄色一级在线视频 | av在线播放不卡 | 国产精品免费久久久久久久久久中文 | 国产免费成人 | 国产精品激情在线观看 | 国外av在线| 69国产盗摄一区二区三区五区 | 日韩在线观看小视频 | 欧美久久影院 | 日韩激情在线 | 人人舔人人射 | 在线看免费 | 免费十分钟 | 久久免费的精品国产v∧ | 狠狠成人 | 在线看中文字幕 | 91女人18片女毛片60分钟 | 久草99 | 久久久久久久久久福利 | 日韩高清一区在线 | 日本黄色大片免费 | 美腿丝袜一区二区三区 | 国产精品久久久久久模特 | 欧美在线91 | 久久久综合九色合综国产精品 | 三级av网| 天天操天天吃 | 欧美成人猛片 | 天天色天天色天天色 | 在线观看国产一区二区 | 99久久国产免费免费 | 一本一本久久a久久精品牛牛影视 | 草莓视频在线观看免费观看 | 国产99在线播放 | 国产精久久久 | 久久尤物电影视频在线观看 | 国产小视频在线观看 | 中文字幕在线网 | 久草在线资源观看 | 日本电影黄色 | 在线小视频你懂得 | 欧美粗又大 | 九九热在线视频 | 国产视频在线观看一区 | 手机成人av在线 | 国产精品永久久久久久久www | 97色涩| 久久久久亚洲精品男人的天堂 | 永久免费视频国产 | a电影在线观看 | 91香蕉视频 mp4 | 国产亚洲精品久久久久久移动网络 | 天天天天色射综合 | 亚洲国产免费看 | 国产精品情侣视频 | 四虎成人精品永久免费av | 婷婷丁香激情网 | 亚洲一区二区视频在线 | 丁香激情五月婷婷 | 免费看的黄色的网站 | 亚洲电影第一页av | 色播五月婷婷 | 成人a毛片| 免费三级骚 | 国产一区二区三精品久久久无广告 | 狠狠狠的干 | 五月婷婷综合激情 | 毛片永久新网址首页 | 亚洲综合激情五月 | 亚洲无吗av | 波多野结衣在线播放视频 | 国产高清av | 5月丁香婷婷综合 | 丁香在线视频 | 国产精品黄色在线观看 | 亚洲免费高清视频 | 亚洲精品人人 | 婷婷色在线资源 | 中文字幕视频免费观看 | 国产精品黄色av | 日本中文字幕在线视频 | 日韩精品一二三 | 精品国产一区二区三区在线观看 | 超级碰碰碰免费视频 | 国产精品久久久久久久久久久久午 | 亚洲天天在线 | 精品一区二区久久久久久久网站 | 亚洲精品免费在线 | 国产精品一区二区三区免费看 | 国产精品97| 欧美日韩高清一区二区三区 | 97香蕉久久国产在线观看 | 欧美成年性 | 日本最大色倩网站www | 午夜影视剧场 | 久久99亚洲精品久久 | 免费久久99精品国产 | 激情偷乱人伦小说视频在线观看 | 国产婷婷久久 | 人人爽人人插 | 在线午夜 | 欧美精品你懂的 | 国产精品成人一区二区三区吃奶 | 日韩免费在线视频观看 | 久久精品国产精品 | 久久久久免费 | 久久艹在线观看 | 99人久久精品视频最新地址 | 亚洲免费一级电影 | 国产成人综合图片 | 在线观看视频免费播放 | 日韩精品一区在线观看 | 中文一区在线观看 | 国产精品久久久毛片 | 中文字幕视频免费观看 | 国产在线观看,日本 | 亚在线播放中文视频 | 欧美日韩国产一区二区三区 | 波多野结衣电影一区二区三区 | 国产一区二区三区免费在线观看 | 国产精品综合在线观看 | 亚洲国产日本 | 日韩av电影一区 | 久久99视频 | 国产自在线观看 | 国产精品久久久久一区二区国产 | 欧美日韩亚洲精品在线 | 国产精品久久电影观看 | 亚洲精品国产第一综合99久久 | 一本之道乱码区 | 欧美国产日韩在线视频 | 久久99国产视频 | www.99在线观看 | 中文字幕免费观看全部电影 | 中文字幕在线人 | 四虎最新入口 | 天天操福利视频 | 免费a网站 | 国产福利在线不卡 | 久久色视频 | 最近免费中文字幕 | 亚洲色图色| 国产一区二区三区四区在线 | 国产又粗又硬又长又爽的视频 | 色婷婷av一区 | 国产区精品在线 | 国产成人精品aaa | 日韩免费中文字幕 | 黄色视屏在线免费观看 | 久久这里只有精品首页 | www黄色 | 欧美久久久久 | 免费在线h | 97超碰人人干 | 最新的av网站| 天天曰视频 | 亚洲男男gaygay无套同网址 | 国产精品 欧美 日韩 | 日韩专区一区二区 | 黄色片网站大全 | 欧美一级片免费在线观看 | 日韩r级电影在线观看 | 国产欧美日韩精品一区二区免费 | 天堂网av 在线 | 四虎影视8848aamm| 99久久精品久久久久久清纯 | 久久久精品免费观看 | 四川bbb搡bbb爽爽视频 | 99国产一区二区三精品乱码 | 在线av资源| 亚洲欧洲精品久久 | 狠狠色丁香婷婷综合久小说久 | 六月色婷 | 日韩在线观看第一页 | 六月激情 | 在线观看av中文字幕 | 免费看国产黄色 | 少妇bbbb | 久久伊人综合 | 国产精品二区在线观看 | 色亚洲激情 | 丁香六月综合网 | 久久视频在线免费观看 | 国产网站在线免费观看 | 欧洲一区二区在线观看 | 欧美日韩一二三四区 | 久草网在线 | 国产剧情久久 | 日日夜夜婷婷 | 国产91在| 婷婷午夜天 | 日韩免费看的电影 | 国产精品片 | 国产精品欧美久久久久三级 | 在线国产小视频 | 992tv人人草 黄色国产区 | 夜夜婷婷 | 免费视频99 | 久久夜色精品国产欧美一区麻豆 | a色网站| 视频在线观看入口黄最新永久免费国产 | a在线免费 | 婷婷激情欧美 | 99久久精品免费看国产免费软件 | 国产小视频在线免费观看 | 91麻豆精品国产自产 | 国产精品久久久久永久免费看 | 黄色av免费看| 亚洲色图22p | 在线岛国av | 天天操天天爱天天干 | 欧美精品在线观看一区 | 久草视频免费在线观看 | 久久精品中文视频 | 久久久国产视频 | 国产第一福利网 | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 天天操月月操 | 97超碰在线免费 | 亚洲 欧美 国产 va在线影院 | 中文字幕在线国产精品 | 激情久久久久久久久久久久久久久久 | 久久精品99视频 | 成人av电影免费观看 | 超碰午夜 | 黄色视屏免费在线观看 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 国产精品一区久久久久 | 久久精品香蕉视频 | 91麻豆精品91久久久久同性 | 亚洲国产三级 | 深爱婷婷网 | 精品国产区 | 午夜国产在线 | 欧美一级在线看 | 玖玖色在线观看 | 91精品免费在线 | 欧美日韩久久不卡 | 九七视频在线 | 麻豆影视在线免费观看 | www.av免费 | 国产在线精品福利 | 国产一级免费片 | 久久国际影院 | 久久这里只有精品1 | 久久久久久久免费观看 | 天天操天天爱天天爽 | 麻豆果冻剧传媒在线播放 | 国产精品99久久久久久小说 | 国产精品6999成人免费视频 | 99国产精品免费网站 | 国产综合激情 | 在线观看91av | av千婊在线免费观看 | 中国美女一级看片 | 最近高清中文字幕 | 三上悠亚在线免费 | 伊人狠狠干 | 欧美日韩二区在线 | 激情五月婷婷综合网 | 精品一区av| 91色吧 | 国产午夜影院 | 成人国产一区 | 久久精品资源 | 久草在线最新视频 | 国产一级大片在线观看 | 日本一区二区免费在线观看 | 亚洲高清在线观看视频 | 国产高清免费av | 国产伦精品一区二区三区高清 | 欧美最猛性xxxx | 日免费视频 | 超碰在线观看99 | 亚洲精品国产精品乱码不99热 | 国产精品九九久久久久久久 | 久久久免费少妇 | 欧美日韩一区二区在线 | 国产99久久久国产精品成人免费 | 国产成人精品午夜在线播放 | 久久久久久久久久亚洲精品 | 免费看片在线观看 | 国产精品入口麻豆 | 国产日韩欧美中文 | 久久一区二区三区日韩 | 国内久久视频 | 国产亚洲成人精品 | 精品一区二区在线播放 | 中文字幕欧美日韩va免费视频 | 日本久久成人中文字幕电影 | 亚洲国产经典视频 | 热久久99这里有精品 | 91视频麻豆视频 | 国产亚洲精品久久久久久移动网络 | 97碰碰碰 | 天天艹天天操 | 在线免费性生活片 | 日本公妇在线观看 | 一区二区电影在线观看 | 青春草免费在线视频 | 国产一区二区三区四区大秀 | 国产精品美女久久久免费 | 久久久影院官网 | 麻豆成人精品 | 8x成人免费视频 | 国产免费观看久久 | 国内外成人在线视频 | 99久高清在线观看视频99精品热在线观看视频 | 一本之道乱码区 | 国产福利精品一区二区 | 免费在线国产视频 | 天天色棕合合合合合合 | 开心婷婷色 | 精品在线观看一区二区三区 | 国产成a人亚洲精v品在线观看 | 99视频免费播放 | 久久一区精品 | 欧美日韩一区二区在线 | 日韩剧情| 亚洲午夜大片 | 97超碰超碰久久福利超碰 | 少妇搡bbbb搡bbb搡69 | 日韩中字在线 | 一区二精品 | 99爱视频在线观看 | 国产亚洲高清视频 | 久久久黄色免费网站 | 麻豆国产精品va在线观看不卡 | 亚洲免费av一区二区 | 日韩网站一区 | 蜜桃麻豆www久久囤产精品 | 欧美在线观看小视频 | 亚洲综合欧美日韩狠狠色 | 999超碰| 国产精品免费观看久久 | 91天天操 | 亚洲理论片在线观看 | 麻豆视频免费在线 | 精品少妇一区二区三区在线 | 97久久久免费福利网址 | 国产精品手机在线播放 | 精品国产乱码久久久久久久 | 毛片3| 在线视频你懂 | 91av在线视频免费观看 | 成人aⅴ视频| 丁香综合 | 91麻豆免费版 | 国产成人精品一区二区三区网站观看 | 午夜久久影视 | 香蕉视频国产在线观看 | 成人91在线 | 在线视频福利 | 亚洲综合欧美日韩狠狠色 | 久久久免费精品视频 | 九九热有精品 | 999久久久欧美日韩黑人 | 婷婷色在线观看 | 奇米网444| 亚洲美女在线国产 | 亚洲欧美在线观看视频 | 日韩毛片精品 | 最新日韩在线 | 色播五月激情五月 | 久久久久视 | 成人免费一级片 | 三级午夜片 | 精品在线小视频 | 精品电影一区二区 | 国产精品久久久久一区二区三区 | 国外av在线 | 中文字幕中文中文字幕 | 99精品视频在线观看免费 | 亚洲影音先锋 | 久久久国产精品麻豆 | 欧美性黑人 | 欧美午夜精品久久久久久浪潮 | 久久黄色影视 | 亚洲欧洲精品一区二区 | 久久热亚洲 | 日本久久久影视 | 在线免费三级 | 不卡av电影在线观看 | 亚洲免费在线看 | 久久久久电影网站 | 天天干天天操天天干 | 91精品一区二区三区蜜桃 | 99精品欧美一区二区 | 久久久久免费网站 | 国产一区久久久 | 日韩天天操 | 久久久久久综合网天天 | 黄色视屏在线免费观看 | 亚洲特级片 | 久久激五月天综合精品 | 中文字幕国产视频 | 丁香花在线视频观看免费 | 五月婷网 | 在线观看中文字幕av | 国产一二三四在线视频 | 国产精品美女999 | 成人av久久 | 精品a级片 | 色综合中文字幕 | 免费国产黄线在线观看视频 | 久久视频 | 美女黄频视频大全 | 91精品国产91热久久久做人人 | 在线观看视频一区二区三区 | 免费观看全黄做爰大片国产 | 欧美亚洲xxx | 天天操天天是 | 午夜av剧场 | 久久精品欧美日韩精品 | 超碰最新网址 | 91亚瑟视频 | 日韩精品免费 | 999久久a精品合区久久久 | 天堂va在线高清一区 | 亚洲免费观看在线视频 | 成人免费视频网站在线观看 | 日韩精品一区在线观看 | 91插插视频| 九九免费精品视频在线观看 | 99久热在线精品视频成人一区 | 久久精品视频免费播放 | 欧美另类成人 | 国内精品久久久久影院优 | 一本色道久久综合亚洲二区三区 | 午夜黄色影院 | 日韩av网址在线 | 精品欧美小视频在线观看 | 成人播放器| 97操操操 | 国产第一页在线观看 | 欧美激情一区不卡 | 成人网在线免费视频 | 黄色成年| 99精品视频在线观看播放 | 国产91精品一区二区绿帽 | 免费观看视频的网站 | 日韩精品在线免费播放 | 亚洲精品在线一区二区 | 亚洲日韩欧美一区二区在线 | 亚洲精品视频免费在线观看 | 不卡av在线 | 亚洲综合狠狠干 | 日韩午夜电影网 | 亚洲日本精品 | 麻豆国产在线视频 | 免费高清影视 |