動态記憶體與智能指針(3)
/**
* 功能:動态記憶體與智能指針
* 時間:2014年7月8日15:33:58
* 作者:cutter_point
*/
#include<iostream>
#include<vector>
#include<memory>
#include<string>
using namespace std;
/**
智能指針和異常
*/
void f()
{
shared_ptr<int> sp(new int(42)); //配置設定一個新對象
//這段代碼抛出一個異常,且在f中未被捕獲
}//在函數結束時shared_ptr自動釋放記憶體
/*
函數退出有兩種可能,正常處理結束或者發生了異常,無論哪種情況,局部對象都會被銷毀
*/
//當發生異常的時候,我們直接管理的記憶體是不會直接釋放的
void fun1()
{
int *ip=new int(42); //動态配置設定一個新對象
//這段代碼抛出一個異常,且在fun1中未被捕獲
delete ip; //在退出之前釋放記憶體
}
/**
智能指針和啞類
*/
struct destination{}; //表示我們正在連接配接什麼;
struct connection{}; //使用連接配接所需的資訊;
connection connect(destination*){} //打開連接配接
void disconnect(connection){} //關閉給定的連結
void f(destination &d/* 其他參數 */)
{
//獲得一個連結;記住使用完後要關閉它
connection c=connect(&d);
//使用連接配接
//如果我們在f退出前忘記調用disconnect,就無法關閉c了
}
/**
使用我們自己的釋放操作
*/
void end_connection(connection *p){disconnect(*p);}
void fun2(destination &d/* 其他參數 */)
{
connection c=connect(&d);
shared_ptr<connection> p(&c, end_connection);
//使用連接配接
//當fun2退出的時候(即使是由于異常退出),connection會被正确關閉
}
/**
unique_ptr
*/
//初始化unique_ptr必須采用直接初始化形式
//由于一個unique_ptr擁有它指向的對象,是以unique_ptr不支援普通的拷貝或指派操作
void fun3()
{
unique_ptr<string> p1(new string("Stegosaurus"));
// unique_ptr<string> p2(p1); //錯誤:unique_ptr不支援拷貝
unique_ptr<string> p3;
// p3=p2; //錯誤:unique_ptr不支援指派
}
void fun4()
{
unique_ptr<string> p1(new string("Stegosaurus"));
// unique_ptr<string> p2(p1); //錯誤:unique_ptr不支援拷貝
// unique_ptr<string> p3;
// p3=p2; //錯誤:unique_ptr不支援指派
//将所有權從p1(指向string Stegosaurus)轉移給p2
unique_ptr<string> p2(p1.release()); //release将p1置為空
unique_ptr<string> p3(new string("Text"));
//将所有權從p3轉移到p2
p2.reset(p3.release()); //reset釋放了p2原來指向的記憶體
}
/**
傳遞unique_ptr參數和傳回unique_ptr
*/
//傳回一個unique_ptr
unique_ptr<int> clone(int p)
{
//正确:從int*建立一個unique_ptr<int>
return unique_ptr<int>(new int(p));
}
//傳回一個局部對象拷貝
unique_ptr<int> fun5(int p)
{
unique_ptr<int> ret(new int(p));
//...
return ret;
}
/**
向unique_ptr傳遞删除器
*/
/*
void fun6()
{
//p指向一個類型為objT的對象,并使用一個類型為delT的對象釋放objT對象
//他會調用一個fcn的delT類型對象
using objT=int;
using delT=int;
delT fcn;
unique_ptr<objT, delT> p(new objT,fcn);
}
有問題!!!!應該用lambda
*/
/*
void fun7(destination &d /* 其他參數//* )
{
connection *pc;
connection c=connect(&d); //打開連接配接
//當p被銷毀時候,連接配接将會關閉
unique_ptr<connection, decltype(end_connection)*)
p(&c, end_connection);
//使用連接配接
//當fun7退出時,即使是異常退出,連接配接也會正常關閉
}
*/
/**
weak_ptr
*/
//weak_ptr是一種不控制所指向對象生存期的智能指針,它指向一個shared_ptr
//管理的對象
//當我們建立一個weak_ptr時,要用一個shared_ptr來初始化它
void fun8()
{
auto p=make_shared<int>(42);
weak_ptr<int> wp(p); //wp弱共享p;p的引用計數未改變
/*
由于對象可能不存在,我們不能使用weak_ptr直接通路對象,而必須調用lock.
lock傳回一個指向共享對象的shared_ptr.
*/
if(shared_ptr<int> np=wp.lock())
{
//如果np不為空則條件成立
//if中,np與p共享對象
}
}
/**
核查指針類
*/
/*
通過使用weak_ptr,不會影響一個給定的StrBlob所指向的vector的生存期。
但是,可以阻止使用者通路一個不再存在的vector的企圖
*/
//對于通路一個不存在的元素的嘗試,StrBlobPtr抛出一個異常
class StrBlobPtr
{
public:
StrBlobPtr():curr(0) {}
StrBlobPtr(StrBlob &a, size_t sz=0):wptr(a.data),curr(sz){}
string& deref() const;
StrBlobPtr &incr(); //字首遞增
private:
//若檢查成功,check傳回一個指向vector的shared_ptr
shared_ptr<vector<string>> check(size_t, const string&) const;
//儲存一個weak_ptr, 意味着底層vector可能會被銷毀
weak_ptr<vector<string>> wptr;
size_t curr; //在數組中的目前位置
};
int main()
{
return 0;
}
PS:不要問我,為什麼要這樣寫,因為我基本吧要寫的都寫到裡面去了,可以看出我是先打好草稿再往上傳的,但是有個問題這節确實是有點亂,好多我搞半天就是實作不了,上網查别人也是這樣寫,但我就是不能搞出來,我不知道是哪根筋沒跳對- -,總之先看過再說,以後回頭再看的時候應該會知道吧,其實作在看到從前寫的那些覺得比較難的,現在看來似乎沒那麼難了,基本現在很輕松就可以搞出來,我是不是有點小進步呢!!
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5CanVXYs9CX0xWdhZWZk9CX09Wbl9lcvRXakVGa49CXy9GdpRWZoh3LcRXZu5ibkN3Yuc2bsJmLjlGdhR3cvw1LcpDc0RHaiojIsJye.gif)