吐槽一下,現在CSDN的編輯器真實太大媽爛!
本實例演示了
std::shared_ptr<T>的初始化的集中方法,
使用上不能使用棧上對象初始化
刪除器的使用
函數傳參的使用
等使用方法
// smart-ptr.cpp: 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include <iostream>
#include <memory>
using namespace std;
class cls
{
public:
cls()
{
printf("cls(), this=%x\r\n", this);
}
~cls()
{
printf("~cls(), this=%x\r\n", this);
}
cls(const cls & a)
{
printf("cls(const cls & a), this=%x\r\n",this);
}
cls(cls && a)
{
printf("cls(cls && a), this=%x\r\n", this);
}
cls& operator=(const cls & a)
{
printf("cls& operator=(const cls &a), this=%x\r\n", this);
}
cls& operator=(const cls && a)
{
printf("cls& operator=(const cls && a), this=%x\r\n", this);
}
};
void func_delete(cls *x)
{
printf("in function deleter\r\n");
delete x;
}
class functor
{
public:
functor()
{
printf("functor(), this=%x\r\n", this);
}
~functor()
{
printf("~functor(), this=%x\r\n", this);
}
functor(const functor & a)
{
printf("functor(const functor & a), this=%x\r\n", this);
}
functor(functor && a)
{
printf("functor(functor && a), this=%x\r\n", this);
}
functor& operator=(const functor & a)
{
printf("functor& operator=(const functor &a), this=%x\r\n", this);
}
functor& operator=(const functor && a)
{
printf("functor& operator=(const functor && a), this=%x\r\n", this);
}
void operator()(cls *x)
{
printf("in functor deleter, this=%x\r\n", this);
delete x;
}
};
void func(std::shared_ptr<cls> *ptra)
{
printf("ptra.use_count()=%d\r\n", ptra->use_count());
}
int main(int argc, char **argv)
{
if (1)
{
/*
本函數演示將shared_ptr作爲函數參數時,shared_ptr的狀態和行爲模式變化。
*/
cls *a = new cls();
std::shared_ptr<cls> ptr(a, std::default_delete<cls>());
func(&ptr);
}
if (0)
{
/*
構建std::shared_ptr的幾種方法
1、使用std::make_shared
2、使用一個shared_ptr初始化另一個shared_ptr
3、使用shared_ptr.reset()
4、使用堆上的裸指針初始化shared_ptr
從本實例也可以看出,在vs2017編譯的程序上,棧上對象的銷燬順序是與他們的聲明順序剛好相反。
*/
cls a, *b = new cls(), *c = new cls();
printf("&a=%x,b=%x,c=%x\r\n", &a, b, c);
std::shared_ptr<cls> ptra = std::make_shared<cls>();//調用了a的無參構造函數
std::shared_ptr<cls> ptrb = std::make_shared<cls>(a);//調用了a的拷貝構造函數
std::shared_ptr<cls> ptra2(ptra); //調用的是std::shared_ptr<T>的拷貝構造函數
std::shared_ptr<cls> ptra3; ptra3.reset(b); //調用shared_ptr<T>.reset()方法
std::shared_ptr<cls> ptra4(c); //使用堆上的指針初始化std::shared_ptr
printf("ptra.use_count()=%d\r\n", ptra.use_count());
printf("ptra.get()=%x\r\n", ptra.get());
printf("ptrb.get()=%x\r\n", ptrb.get());
printf("ptra2.get()=%x\r\n", ptra2.get());
printf("ptra3.get()=%x\r\n", ptra3.get());
printf("ptra4.get()=%x\r\n", ptra4.get());
}
if (0)
{
/*
這種寫法會引起程序假死,不管a是自定義類型還是基礎類型。
當shared_ptr指向的指針內存被釋放掉之後,在執行shared_ptr的析構函數,就會假死。
即://ERROR!!! 當將a託管給shared_ptr之後,a就不可以手動刪除。
即:不能用棧上的對象去初始化std::shared_ptr。
*/
cout << "--------------------------" << endl;
cls a;
std::shared_ptr<cls> ptra3(&a);
}
if (0)
{
/*
智能指針會託管交給他的對象,當將a託管給shared_ptr之後,a就不可以手動刪除。
*/
cout << "--------------------------" << endl;
cls *a = new cls();
std::shared_ptr<cls> ptra(a);
printf("ptra.use_count()=%d\r\n", ptra.use_count());
//delete a; a = nullptr;//ERROR!!!
printf("ptra.use_count()=%d\r\n", ptra.use_count());
cls *pa = ptra.get();
printf("*pa=%d\r\n", pa);
}
if (0)
{
/*
本示例演示給std::shared_ptr<>設置刪除器
1、默認刪除器
2、lambda刪除器
3、函數指針刪除器
4、仿函數刪除器
*/
cout << "--------------------------" << endl;
cls *a = new cls();
std::shared_ptr<cls> ptr(a, std::default_delete<cls>());
cls *b = new cls();
std::shared_ptr<cls> ptr2(b, [](cls *x)->void {
printf("in lambda deleter\r\n");
delete x;
});
cls *c = new cls();
std::shared_ptr<cls> ptr3(c,func_delete);
cls *d = new cls();
std::shared_ptr<cls> ptr4(d, functor());
std::shared_ptr<cls> ptr5(ptr4);
/*
一組可能的打印如下:注意一下,如果使用函數對象作爲析構器,要進行高達4此構造!
--------------------------
cls(), this=608100
cls(), this=608130
cls(), this=607ef0
cls(), this=6081f0
functor(), this=1ff67c
functor(functor && a), this=1ff578
functor(functor && a), this=1ff44c
functor(functor && a), this=60d024
~functor(), this=1ff44c
~functor(), this=1ff578
~functor(), this=1ff67c
in functor deleter, this=60d024
~cls(), this=6081f0
~functor(), this=60d024
in function deleter
~cls(), this=607ef0
in lambda deleter
~cls(), this=608130
~cls(), this=608100
--------------------------
*/
}
cout << "--------------------------" << endl << endl;
return 0;
}