C++智能指針(二)模擬實現三種智能指針

https://blog.csdn.net/nou_camp/article/details/70186721

在上一篇博客中提到了Auto_ptr(C++智能指針(一)),下面進行模擬實現Auto_ptr?
采用類模板實現

#include<iostream>
using namespace std;
template<class T>
class Autoptr
{
public:Autoptr(T* ptr = NULL):_ptr(ptr){}//Autoptr():_ptr(NULL)//{}Autoptr(Autoptr<T>& ap){this->_ptr = ap._ptr;ap._ptr = NULL;}Autoptr<T>& operator=(Autoptr<T>& sp){if (this != &sp){delete this->_ptr;_ptr = sp._ptr;sp._ptr = NULL;}return *this;}T* operator->(){return _ptr;}T operator*(){return *_ptr;}~Autoptr(){delete _ptr;_ptr = NULL;}void  Reset(T* ptr = 0){if (_ptr != ptr){delete  _ptr;}_ptr = ptr;}
protected:T* _ptr;
};void test()
{//int *p1 = new int(10);//Autoptr<int>ap1(p1);Autoptr<int> ap1(new int(10));//上面的兩行代碼可以直接用本行代碼代替cout << *ap1 << endl;Autoptr<int> ap2(ap1);cout << *ap2 << endl;Autoptr<int> ap3(new int(20));ap3 = ap2;cout << *ap3 << endl;//cout << *ap1 << endl;//會使代碼出錯
}
int main()
{test();system("pause");return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

這里寫圖片描述?
這里寫圖片描述


//cout << *ap1 << endl;//會使代碼出錯?
這是test函數中的代碼,執行這句代碼,會使程序崩潰,這是因為ap1已經把它指向的空間交給了ap2去管理,所以ap1已經不具備訪問原來自己所指向的空間的權限。所以對它進行解引用是非法的。?
所以可以看清auto_ptr的本質是管理權的轉移,即ap1將自己所指向的空間交給ap2來管理,析構也是由ap2來完成。


由上面可知auto_ptr有嚴重缺陷,所以后來有人寫了scopedptr,慢慢發展形成了第三方庫。?
scopedptr ->防拷貝,意思就是不能進行拷貝,簡單地說是一種簡單粗暴的方式。下面模擬實現scopedptr。采用模板類實現。

template<class T>
class scopedptr
{
public:scopedptr(T *ptr):_ptr(ptr){}T* operator->(){return _ptr;}T operator*(){return *_ptr;}~scopedptr(){delete _ptr;_ptr = NULL;}
protected:scopedptr<T>& operator=(const scopedptr<T>& s);scopedptr(scopedptr<T>& ap);
private:T* _ptr;
};
void test()
{scopedptr<int> s1(new int(10));//scopedptr<int> s2(s1);//有錯誤,編譯不通過cout << *s1 << endl;
}
int main()
{test();system("pause");return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

scopedptr中對拷貝構造函數和賦值運算符的重載函數只是進行了聲明,并沒有去定義這兩個函數,而且聲明為protected或者是private,這是防止別人在類外對這兩個函數進行定義。防止拷貝,所以說scopedptr是一種簡單粗暴的方式。


編寫程序往往要用到拷貝,這樣scopedptr就不能起到相應的作用,所以便有了shared_ptr。?
shared_ptr->采用了引用計數,優點是功能強大,但是也有缺點,缺點是過于復雜,而且會引起循環引用。?
下面模擬實現shared_ptr

#include<iostream>
using namespace std;
template<class T>
class sharedptr
{
public:sharedptr(T* ptr) //構造:_ptr(ptr), _refcount(new int(1)){}sharedptr() //構造:_ptr(NULL), _refcount(new int(1)){}sharedptr(const sharedptr<T>& sp) //拷貝構造:_ptr(sp._ptr), _refcount(sp._refcount){(*_refcount)++;}sharedptr<T>& operator=(const sharedptr<T>& sp) //賦值運算符的重載{if (_ptr != sp._ptr){delete _ptr;delete _refcount;_ptr = sp._ptr;_refcount = sp._refcount;++(*_refcount);}return *this;}~sharedptr() //析構{Realease();}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}T Getrefcount(){return *(_refcount);}inline void Realease(){if (--*_refcount == 0){delete _refcount;delete _ptr;}}void  Reset(T* ptr ,T* refcount){if (_ptr != ptr){delete  _ptr;delete _refcount;}_ptr = ptr;_refcount = refcount;}
public:T* _ptr;T* _refcount;//T _refcount;//有缺陷//int static _refcount;//有缺陷
};
void test()
{sharedptr<int> s1(new int(10));//cout << *s1._refcount << endl;cout << s1.Getrefcount() << endl;sharedptr<int> s2(s1);//cout << *s2._refcount << endl;cout << s2.Getrefcount() << endl;sharedptr<int> s3(new int(20));s3 = s1;//cout << *s3._refcount << endl;cout << s3.Getrefcount() << endl;
}
int main()
{test();//*sharedptr<int> sp;  // 驗證Reset//sp.Reset(new int,new int(1));       //*sp = 10;//cout << *sp << endl;//sp.Reset(new int, new int(1));  //*sp = 20;//cout << *sp << endl;//sp.Reset(); system("pause");return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96

這里寫圖片描述


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383752.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383752.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383752.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Prime Distance On Tree-樹分治+FFT

題目描述 Problem description. You are given a tree. If we select 2 distinct nodes uniformly at random, what’s the probability that the distance between these 2 nodes is a prime number? Input The first line contains a number N: the number of nodes in this…

C++智能指針(三)總結

https://blog.csdn.net/nou_camp/article/details/70195795 在上一篇博客中&#xff08;C智能指針&#xff08;二&#xff09;&#xff09;模擬實現了三種智能指針。 其中最好的就是shared_ptr,但是這并不代表它就是最完美的&#xff0c;它也有問題&#xff0c;這個問題就是循環…

POJ2114-Boatherds-樹分治

題目描述 Boatherds Inc. is a sailing company operating in the country of Trabantustan and offering boat trips on Trabantian rivers. All the rivers originate somewhere in the mountains and on their way down to the lowlands they gradually join and finally th…

c++11 你需要知道這些就夠了

https://blog.csdn.net/tangliguantou/article/details/50549751c11新特性舉著火把尋找電燈今天我就權當拋磚引玉&#xff0c;如有不解大家一起探討。有部分內容是引用自互聯網上的內容&#xff0c;如有問題請聯系我。T&& 右值引用 std::move 右值引用出現之前我們只能…

HDU5977-Garden of Eden-樹分治+FWT

題目描述 When God made the first man, he put him on a beautiful garden, the Garden of Eden. Here Adam lived with all animals. God gave Adam eternal life. But Adam was lonely in the garden, so God made Eve. When Adam was asleep one night, God took a rib fro…

C++11新特性學習

https://blog.csdn.net/tennysonsky/article/details/778170481、什么是C11C11標準為C編程語言的第三個官方標準&#xff0c;正式名叫ISO/IEC 14882:2011 - Information technology -- Programming languages -- C。在正式標準發布前&#xff0c;原名C0x。它將取代C標準第二版I…

C++ override 關鍵字用法

override關鍵字作用&#xff1a; 如果派生類在虛函數聲明時使用了override描述符&#xff0c;那么該函數必須重載其基類中的同名函數&#xff0c;否則代碼將無法通過編譯。舉例子說明struct Base {virtual void Turing() 0;virtual void Dijkstra() 0;virtual void VNeumann…

Gym - 101981I-MagicPotion-最大流

題目描述 There are n heroes and m monsters living in an island. The monsters became very vicious these days, so the heroes decided to diminish the monsters in the island. However, the i-th hero can only kill one monster belonging to the set Mi. Joe, the st…

c++仿函數 functor

https://www.cnblogs.com/decade-dnbc66/p/5347088.html內容整理自國外C教材先考慮一個簡單的例子&#xff1a;假設有一個vector<string>&#xff0c;你的任務是統計長度小于5的string的個數&#xff0c;如果使用count_if函數的話&#xff0c;你的代碼可能長成這樣&#…

HDU4812-D Tree-樹分治

題目描述 There is a skyscraping tree standing on the playground of Nanjing University of Science and Technology. On each branch of the tree is an integer (The tree can be treated as a connected graph with N vertices, while each branch can be treated as a v…

成為C++高手之實戰項目

https://blog.csdn.net/niu_gao/article/details/51458721 在內存中模擬出一副牌&#xff0c;然后模擬洗牌&#xff0c;發牌等動作。 流程是這樣的&#xff1a;構建一副牌保存到一個數組中—洗牌—創建玩家—向玩家發牌–輸出每個玩家的牌。 #include <stdio.h> #include…

C++中String類的實現

https://www.cnblogs.com/zhizhan/p/4876093.html原文&#xff1a;http://noalgo.info/382.html String是C中的重要類型&#xff0c;程序員在C面試中經常會遇到關于String的細節問題&#xff0c;甚至要求當場實現這個類。只是由于時間關系&#xff0c;可能只要求實現構造函數、…

Ubuntu軟件更新失敗

剛安裝好Ubuntu以后需要將系統的軟件都更新一下&#xff0c;但是遇到一個問題就是下載倉庫信息失敗&#xff0c;大概是這個樣子的錯誤&#xff1a; 經國遇到這樣的問題可以試一下下面這個命令&#xff1a; sudo rm -rf /var/lib/apt/lists/* sudo apt-get update參考網址&…

getsockname函數與getpeername函數的使用

https://www.tuicool.com/articles/V3Aveygetsockname和getpeername函數 getsockname函數用于獲取與某個套接字關聯的本地協議地址 getpeername函數用于獲取與某個套接字關聯的外地協議地址 定義如下&#xff1a;[cpp] view plaincopy#include<sys/socket.h> int gets…

Ubuntu根目錄空間不足

自己在固態硬盤上安裝的Ubuntu&#xff0c;結果只用了一天就顯示磁盤空間不足。查看空間以后發現Ubuntu自己安裝的時候默認給根目錄分配的是10GB,然而我們下載的軟件以及環境等一般都安裝在根目錄空間下&#xff0c;尤其是/usr目錄所占的空間很大。 不得已我在網上查找了如何給…

Linux命令【一】基本命令

shell命令和bash命令相同&#xff0c;指的是命令解析器 快捷鍵 history 所有的歷史命令ctrl P 向上滾動命令 ctrl N 向下滾動命令 ctrlB將光標向前移動 ctrlF將光標向后移動 ctrlA移動到命令行頭部 ctrlE移動到命令行尾部 光標刪除操作&#xff1a;刪除光標前面字符ctrlh或…

The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

http://www.jb51.net/article/119654.htmThe MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 意思貌似MYSQL還運行在 --skip-grant-tables模式&#xff0c;如何讓他回到原來的模式 第一種方法&#xff1a;原來在mysql.ini文…

解決Ubuntu“下載額外數據文件失敗 ttf-mscorefonts-installer”的問題

參考博客&#xff1a;傳送門 下載[ttf-mscorefonts-installer.zip](https://pan.baidu.com/s/1i5rLfMH) 密碼: h76g 然后解壓到下載的目錄&#xff0c;在當前目錄執行命令&#xff1a; sudo dpkg-reconfigure ttf-mscorefonts-installer這條命令手動指定文件夾的位置,重新配置…

【C語言】單鏈表的相關熱點面試題(包括:從尾到頭打印,逆置,冒泡,尋找中間節點,倒數k節點)

https://blog.csdn.net/hanjing_1995/article/details/51539599從尾到頭打印單鏈表[cpp] view plaincopyvoid FromTailToHeadPrint(SListNode*& head) { stack<SListNode*> s; SListNode* cur head; while (cur) { s.push(cur); …

Linux命令【二】終端+Vim

需要先安裝net-tools ifconfig eth0 網卡&#xff0c;硬件地址為MAC 地址&#xff0c;網卡編號&#xff0c;絕對不會重復 lo 回環地址 測試兩臺主機之間能否通信&#xff1a;ping IP或域名 [-c 4//回饋四條信息 -i//每隔多少秒回饋一次] 得到域名對應的IPnslookup 域名得到域…