#include
#include
#include
using namespace std;
int main()
{
shared_ptr<string>pstring = make_shared<string>("Hello"); // ()内部初始化方式为<类型>的初始化模式
shared_ptr<string>pstring = make_shared<string>(10, 'p'); // ← 意义同上
cout<<*pstring;// 使用 * 可以对指针进行解引用
return 0;
}
②方便起见可以使用auto来进行对智能指针的类型声明
#include
#include
#include
using namespace std;
int main()
{
auto pstring = make_shared<string>(10, 'p');
cout << *pstring;
return 0;
}
③shared_ptr的赋值与引用计数
#include
#include
#include
using namespace std;
int main()
{
auto pstring = make_shared<string>(10, 'p');
auto q = pstring;
auto r = pstring;
cout << pstring.use_count(); // use_count()这时的值为3
{
auto q = pstring;
auto r = pstring;
cout << pstring.use_count(); // use_count()这时的值为5
} // 离开局部作用域会导致,局部作用域内部的智能指针被销毁
cout << pstring.use_count(); // use_count()这时的值为3
return 0;
}
④Str_Blob类
#include
#include
#include
#include
#include
using namespace std;
class StrBlob
{
public:
typedef vector<string>::size_type size_type;
StrBlob();
StrBlob(initializer_list<string> il);
size_type size() const
{
return data->size();
}
bool empty() const
{
return data->empty();
}
// 添加和删除元素
void push_back(const string& t)
{
data->push_back(t);
}
void pop_back();
// 元素访问
string& front();
string& back();
string& front()const;
string& back()const;
private:
shared_ptr<vector<string>> data;
void check(size_type i, const string& msg) const;
};
StrBlob::StrBlob() : data(make_shared<vector<string>>())
{
}
StrBlob::StrBlob(initializer_list<string>li) :data(make_shared<vector<string>>(li))
{
}
void StrBlob::check(size_type i, const string& msg)const
{
if (i >= data->size())
{
throw out_of_range(msg);
}
}
string& StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
string& StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
string& StrBlob::front()const
{
check(0, "front on empty StrBlob");
return data->front();
}
string& StrBlob::back()const
{
check(0, "back on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
check(0, "pop back on empty StrBlob");
data->pop_back();
}
int main()
{
StrBlob b1;
{
StrBlob b2 = { "a", "an", "the" };
b1 = b2;
b2.push_back("about");
cout << b1.size() << " " << b2.size() << endl;;
}
cout << b1.size(); // 这里的b1并没有被直接随着b2的销毁而销毁
return 0;
}
⑤shared_ptr与new结合使用(不可以使用由new创建的指针来隐式转换智能指针)
#include
using namespace std;
shared_ptr<int> clone(int p)
{
// 这里采用了初始化的方式来使用普通指针初始化智能指针
return shared_ptr<int>(new int(p)); // 这里涉及面向返回值类型的隐式转换 | 返回值必须要将普通指针绑定到智能指针上
}
int main()
{
int p = 100;
shared_ptr<int>pointer = clone(p);
*pointer += 1;
cout << *pointer;
return 0;
}
⑥unique_ptr的初始化与赋值
#include
using namespace std;
int main()
{
unique_ptr<int>p(new int(42));
cout << *p << endl;
unique_ptr<int>q;
//q = p;//这种行为被禁止,不允许p在释放前赋值
//q = p.release(); // 不允许赋值
q.reset(p.release()); //将unique_ptr的控制权转让,重置q绑定的内存
cout << *q << endl;
// cout << *p << endl; // 会发生堆栈异常 *p已经被释放
return 0;
}
⑦可以拷贝将亡的unique_ptr以及unique_ptr的局部对象
#include
using namespace std;
unique_ptr<int> clone_1(int p)
{
return unique_ptr<int>(new int(p)); //拷贝将亡值
}
unique_ptr<int> clone_2(int p)
{
unique_ptr<int>ret = unique_ptr<int>(new int(p)); //可以拷贝将返回的局部对象
return ret;
}
int main()
{
int p = 10;
unique_ptr<int> c1(clone_1(p));
unique_ptr<int> c2(clone_2(p));
cout << *c1 << "\n" << *c2 << endl;
return 0;
}
⑧ 习题 12.19
#include
#include
#include
#include
#include
#include
using namespace std;
class StrBlobPtr;
class StrBlob
{
friend class StrBlobPtr;
public:
typedef vector<string>::size_type size_type;
StrBlob() : data(make_shared<vector<string>>())
{
}
StrBlob(initializer_list<string> il):data(make_shared < vector<string>>(il))
{
}
size_type size() const
{
return data->size();
}
bool empty()const
{
return data->empty();
}
// 添加和删除元素
void push_back(const string& t)
{
data->push_back(t);
}
void pop_back()
{
check(0, "pop back on empty StrBlob");
data->pop_back();
}
// 元素访问
string& front()
{
// 如果vector为空check会抛出一个异常
check(0, "front on empty StrBlob");
return data->front();
}
const string& front()const
{
check(0, "front on empty StrBlob");
return data->front();
}
string& back()
{
// 如果vector为空check会抛出一个异常
check(0, "back on empty StrBlob");
return data->back();
}
const string& back()const
{
check(0, "back on empty StrBlob");
return data->back();
}
// 提供给 StrBlobPtr 的接口
StrBlobPtr begin();
StrBlobPtr end();
private:
shared_ptr<vector<string>>data;
void check(size_type i, const string& msg)const
{
if (i >= data->size())
{
throw out_of_range("msg");
}
}
};
// 当试图访问一个不存在的元素的时候,StrBlob抛出一个异常
class StrBlobPtr
{
friend bool eq(const StrBlobPtr&, const StrBlobPtr&);
public:
StrBlobPtr() :curr(0)
{
}
StrBlobPtr(StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz)
{
}
string& deref()const
{
auto p = check(curr, "dereference past end");
return (*p)[curr]; // 否则,返回指向vector的shared_ptr
}
StrBlobPtr& incr() // 前缀递增
{
check(curr, "increment past the end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr& decr() // 前缀递减
{
--curr;
check(-1, "decrement past the begin of StrBlobPtr");
return *this;
}
private:
shared_ptr<vector<string>>check(size_t i, const string& msg) const
{
auto ret = wptr.lock();
if (!ret)
{
throw runtime_error("unbound StrBlobPtr");
}
if (i >= ret->size())
{
throw out_of_range(msg);
}
return ret; // 否则,返回指向vector的shared_ptr
}
weak_ptr<vector<string>>wptr;
size_t curr; // 在数组中的当前位置
};
inline bool eq(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
// 若底层的vector是同一个
if (l == r)
{
// 则两个指针都指向空,或者指向相同元素的时候,它们相等
return (!l || lhs.curr == rhs.curr);
}
else
{
return false; // 若指向不同的vector则不可能相等
}
}
inline bool neq(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{
return !eq(lhs, rhs);
}
inline StrBlobPtr StrBlob::begin()
{
return StrBlobPtr(*this);
}
inline StrBlobPtr StrBlob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
int main()
{
StrBlob b1;
{
StrBlob b2 = { "a","an","the" };
b1 = b2;
b2.push_back("about");
cout << b2.size() << endl;
}
cout << b1.size() << endl;
cout << b1.front() << " " << b1.back() << endl;
const StrBlob b3 = b1;
cout << b3.front() << " " << b3.back() << endl;
for (auto it = b1.begin(); neq(it, b1.end()); it.incr())
{
cout << it.deref() << endl;
}
return 0;
}
⑨ unique_Ptr自动管理动态数组
#include
using namespace std;
int main()
{
unique_ptr<int[]>up(new int[10]); // 定义指向10个元素的数组指针
up.release(); // 销毁刚刚定义过的指针
//为数组中的元素赋值
for (int i = 0; i < 10; i++)
{
up[i] = i;
}
return 0;
}
⑩ shared_Ptr手动管理动态数组
#include
using namespace std;
int main()
{
shared_ptr<int[]>sp(new int[10], [](int* p) {delete p; }); // 以lambda表达式的方式定义删除器
// sp.reset(); // 使用自定义的删除器来执行智能指针指向数组的释放
// 元素访问方式略有差别,shared_ptr不可以使用下标
for (int i = 0; i < 10; i++)
{
*(sp.get() + i) = i;
}
for (int i = 0; i < 10; i++)
{
cout << sp[i] << "\t";
}
}
11.allocator使用案例一
#include
using namespace std;
int main()
{
allocator<string>alloc;
auto const p = alloc.allocate(100); // 分配100个未初始化的string对象
string s;
string* q = p; // q指向第一个string
while (cin >> s && q != p + 100)
{
alloc.construct(q++, s); //用s初始化*q
}
const size_t size = q - p; // 记住读取了多少个string
// 使用数组
for (size_t i = 0; i < size; i++)
{
cout << p[i] << "\t";
}
while (q != p) // 使用完毕释放已构造的string
{
alloc.destroy(--q);
}
alloc.deallocate(p, 100); // 释放内存
return 0;
}
12.allocator使用案例二
#include
using namespace std;
int main()
{
allocator<int> alloc;
auto const p = alloc.allocate(10);
int* q = p;
int count = 10;
while (count--)
{
int x;
cin >> x;
*q++ = x;
}
int size = q - p;
for (int i = 0; i < size; i++)
{
cout << p[i] << " ";
}
return 0;
}