您的位置:首页 > 编程语言 > C语言/C++

C++11 智能指针——shared_ptr

2016-03-07 22:22 543 查看
shared_ptr是C++11中最智能的指针,它使用引用计数,当使用一个shared_ptr构造或赋值给另外一个shared_ptr时,
引用计数+1.当一个shared_ptr销毁时引用计数-1,直到引用计数为0时,delete掉申请的资源。

问题:
1.关于shared_ptr()构造:shared_ptr<int> ipNull();这里的ipNUll会被解释为function,不可以作为左值
使用。如果要声明一个原始指针为null且引用计数为0的shared_ptr应该使用:shared_ptr<int> ipNull;
2.shared_ptr不可交叉引用,若要交叉引用,则应该使用weak_ptr


—————————————————————————

shared_ptr的简单使用

#include <iostream>
#include <memory>
#include <cstdio>

using namespace std;

int main()
{
//*<constructor:>*//
shared_ptr<int> sipnull();              //create a shared_ptr,but it manager a nullptr and it's reference-count is zero
shared_ptr<int> sip(new int(13));       //create a new obj,it's reference-count is one
shared_ptr<int> sip1(sip);              //cause reference-count increase to two

sipnull.reset(new int(12));         //ERROR:".reset"的左边必须有类/结构/联合...
//sipnull = sip;                        //ERROR:C2659,此错误是编译器将左边变量类型解释为函数造成的
//正确的用法是:shared_ptr<int> sipnull;
cout << "sip and sip1 reference-count is:"
<< sip.use_count() << endl;        //cout :"sip and sip1 reference-count is:2"

cout << "sip & sip1 is not null?" << boolalpha << sip.operator bool() << endl;
//"sip & sip1 is not null?true"

//*<modify value:>*//
int *p = sip.get();                     //return the pointer shared_ptr manager to a raw pointer
*p = 1314520;                           //modify *sip
cout << "anfter *p = 1314520,*sip = "
<< *sip << endl;                   //cout :*sip = 1314520

//*<compare two shared_ptr:>*//
*sip = 12;
cout << "sip == sip1? " << boolalpha
<< (sip == sip1) << endl;           //cout:"sip == sip1? true"
sip1.reset(new int(12));                //sip reference-count reduce one
cout << "sip == sip1? " << boolalpha
<< (sip == sip1) << endl;          //cout:"sip == sip1? false"

//in fact:operator == is equal sip.get() == sip1.get(),it compares the raw pointer!!!

//*<manager a local pointer:illegalety>*//
int i = 74;
printf("%x\r\n", &i);
shared_ptr<int> sip2(&i);               //shared_ptr manager a local variable

*sip2 = 89;
cout << "i = " << *sip2 << endl;        // "i = 89"
getchar();                              //before this,all normal
return 0;//cause an interrupting,
//because a point not allocated by new was delete when shared_ptr self-destroy
}


—————————————————————————

shared_ptr中使用工厂函数make_shared以及shared_ptr在vector中的使用

//2016-03-07 shared_ptr之make_shared以及STL container
#include <memory>
#include <vector>
#include <iostream>
using namespace std;

class sclass {
private:
int m_i;
public:
sclass():m_i(0){}
sclass(const int &i) :m_i(i) {}
void operator = (const int i) { m_i = i; }
~sclass() {
cout << "destroty:" << m_i << endl;
}
//ERROR if no keyword "friend",because << access private member variable
friend ostream & operator<<(ostream &os,const sclass & in) {
os << in.m_i;
return os;
}
};

//*<use shared_ptr self-deftroy>*//
void test(const int in) {
shared_ptr<sclass> sia(new sclass(in));
}

//*<use make_shared>*//
void test_vector() {
vector<shared_ptr<sclass> > vsi;
for (int i = 0; i < 10; ++i) {
auto ai = make_shared<sclass>((i + 1) * 2);
vsi.push_back(ai);
}
}
//*<1.shared_ptr工厂函数的使用 2.shared_ptr使用于容器>*//
int main()
{
//*<use shared_ptr self-deftroy>*//
test(5);
//*<use make_shared>*//
auto aui = make_shared<sclass>(10);
cout << "aui = " << *aui << endl;

//*<use in STL container>*//
test_vector();
while (1);
return 0;
}




—————————————————————————

使用shared_ptr构建生产者模型(见《boost完全开发指南》——罗剑锋著p76)

class abstract {
protected:
virtual ~abstract() = default;//除了abstract以及其子类,不可显示的调用delete
public:
virtual void func() = 0;      //纯虚函数
};

class implet:public abstract
{
public:
implet() = default;
virtual ~implet() = default;

public:
virtual void func() {
cout << "class implit func" << endl;
}

};

shared_ptr<abstract> create() {
return make_shared<implet>();
}

//*<工厂模式 >*//
int main()
{
//*<use producer-mode>*//
auto afunc= create();
afunc->func();
while (1);
return 0;
}


//add 2016-03-08 使用删除器,让shared_ptr适用于数组 //

#include <memory>
#include <iostream>
#include <string>

using namespace std;

class sclass {
private:
int m_i;
public:
sclass():m_i(0){}
sclass(const int &i) :m_i(i) {}
void operator = (const int i) { m_i = i; }
~sclass() {
cout << "destroty:" << m_i << endl;
}
friend ostream & operator<<(ostream &os,const sclass & in) {
os << in.m_i;
return os;
}
};

void test(const int in) {
//使用lambda表达式,订制shared_ptr的deleter
shared_ptr<sclass> sia(new sclass[in], [](sclass *sc) {delete[] sc; });
for (int i = 0; i < in; ++i) {
sia.get()[i] = (i + 1)*(i - 1);
}
}

int main()
{
test(5);      //创建5个sclass对象
while (1);
return 0;
}


输出结果:



注意:unique_ptr管理数组的时候,使用的是unique_ptr < class[]>,而shared_ptr却使用的是shared_ptr。因为unique_ptr在C++11中有对unique_ptr []的支持,有默认的delete [],而shared_ptr却没有实现数组的支持,只能通过重载shared_ptr的deleter来实现数组的管理。但是不管是unique_ptr还是shared_ptr管理数组,实际上都是管理的数组指针!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息