练习16.28:
简易的shared_ptr代码如下
#include <iostream>
#include <vector>
#include <list>
using namespace std;
//shared_ptr模板
template<typename T>class SharedPtr {
friend SharedPtr<T>& MakeShared(T* t);
public:
//默认初始化
SharedPtr() :ptr(nullptr), user(nullptr) { }
//传入指向T的指针进行构造,防止隐式类型转换
explicit SharedPtr(T* p = nullptr) :ptr(p), user(new size_t(1)) { }
//拷贝构造
SharedPtr(const SharedPtr& sp) :ptr(sp.ptr), user(sp.user)
{
if (user != nullptr)
{
++* user;
}
}
//析构函数
~SharedPtr();
//赋值运算符
SharedPtr& operator=(const SharedPtr&);
//解引用运算符
T& operator*() { return *ptr; }
//常量版本
T& operator*()const { return *ptr; }
//返回指针
T* get() { return ptr; }
size_t use_count() { return *user; }
bool unique()
{
if (use_count == 1)
{
return true;
}
else
{
return false;
}
}
private:
//指向T类型的指针
T* ptr;
//指向计数器的指针
size_t* user;
};
//定义make_shared
template<typename T>
SharedPtr<T> MakeShared(T* t)
{
T* ptr = t;
return SharedPtr<T>(ptr);
}
//赋值运算符
template<typename T>
SharedPtr<T>& SharedPtr<T>::operator=(const SharedPtr& sp)
{
if (this != sp)
{
if (user == nullptr)
{
--* user;
if (*user == 0)
{
delete ptr;
delete user;
}
}
ptr = sp.ptr;
if (sp.user != nullptr)
{
++* sp.user;
}
user = sp.user;
}
return *this;
}
//析构函数
template<typename T>
SharedPtr<T>::~SharedPtr()
{
if (user != nullptr)
{
--* user;
if (*user == 0)
{
delete ptr;
delete user;
}
}
}
int main()
{
SharedPtr<string>sp1(new string("hello"));
SharedPtr<string>sp2 = MakeShared<string>(new string("world"));
SharedPtr<int>sp3 = MakeShared<int>(new int(666));
cout<<*sp1<<endl;
cout << *sp2 << endl;
cout << *sp3 << endl;
system("pause");
return 0;
}
结果如下:
unique_ ptr代码如下:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
//shared_ptr模板
template<typename T>class UniquePtr {
public:
//默认初始化
UniquePtr() :ptr(nullptr){ }
//传入指向T的指针进行构造,防止隐式类型转换
explicit UniquePtr(T* p) :ptr(p) { }
//析构函数
~UniquePtr();
//不能拷贝,不能赋值运算符,定义为删除的函数
UniquePtr(const UniquePtr&) = delete;
UniquePtr& operator=(const UniquePtr&) = delete;
//解引用运算符
T& operator*() { return *ptr; }
//常量版本
T& operator*()const { return *ptr; }
//u放弃对指针的控制权,返回指针,并将u置为空
T* release();
//释放u指向的对象,如果传入了内置指针,则使u指向这个对象,否则指控
void reset();
void reset(T* p);
private:
//指向T类型的指针
T* ptr;
};
//u放弃对指针的控制权,返回指针,并将u置为空
template<typename T>
T* UniquePtr<T>::release()
{
auto temp = ptr;
if (ptr != nullptr)
{
ptr == nullptr;
}
return temp;
}
//释放u指向的对象,如果传入了内置指针,则使u指向这个对象,否则指控
template<typename T>
void UniquePtr<T>::reset()
{
if (ptr != nullptr)
{
delete ptr;
ptr == nullptr;
}
}
template<typename T>
void UniquePtr<T>::reset(T* p)
{
if (ptr != nullptr)
{
delete ptr;
}
ptr = p;
}
//析构函数
template<typename T>
UniquePtr<T>::~UniquePtr()
{
if (ptr != nullptr)
{
delete ptr;
}
}
int main()
{
UniquePtr<string>sp1(new string("hello"));
UniquePtr<string>sp2;
UniquePtr<int>sp3(new int(666));
cout << *sp1 << endl;
cout << *sp3 << endl;
cout << endl;
sp2.reset(new string("world"));
sp1.release();
system("pause");
return 0;
}
结果为:
练习16.29:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
//shared_ptr模板
template<typename T>class SharedPtr {
friend SharedPtr<T>& MakeShared(T* t);
public:
//默认初始化
SharedPtr() :ptr(nullptr), user(nullptr) { }
//传入指向T的指针进行构造,防止隐式类型转换
explicit SharedPtr(T* p = nullptr) :ptr(p), user(new size_t(1)) { }
//拷贝构造
SharedPtr(const SharedPtr& sp) :ptr(sp.ptr), user(sp.user)
{
if (user != nullptr)
{
++* user;
}
}
//析构函数
~SharedPtr();
//赋值运算符
SharedPtr& operator=(const SharedPtr&);
//解引用运算符
T& operator*() { return *ptr; }
//常量版本
T& operator*()const { return *ptr; }
//返回指针
T* get() { return ptr; }
size_t use_count() { return *user; }
bool unique()
{
if (use_count == 1)
{
return true;
}
else
{
return false;
}
}
private:
//指向T类型的指针
T* ptr;
//指向计数器的指针
size_t* user;
};
template<typename T, class ...Args>
SharedPtr<T>MakeShared(Args&&...args)
{
return SharedPtr<T>(new T(std::forward<Args>(args)...));
}
//赋值运算符
template<typename T>
SharedPtr<T>& SharedPtr<T>::operator=(const SharedPtr& sp)
{
if (this != sp)
{
if (user == nullptr)
{
--* user;
if (*user == 0)
{
delete ptr;
delete user;
}
}
ptr = sp.ptr;
if (sp.user != nullptr)
{
++* sp.user;
}
user = sp.user;
}
return *this;
}
//析构函数
template<typename T>
SharedPtr<T>::~SharedPtr()
{
if (user != nullptr)
{
--* user;
if (*user == 0)
{
delete ptr;
delete user;
}
}
}
//声明,类模板与函数模板的声明
template<typename>class BlobPtr;
template<typename>class Blob;
template<typename>class SharedPtr;
template<typename T>
bool operator==(const Blob<T>&, const Blob<T>&);
template<typename T>class Blob {
//每个Blob实例将访问权限授予用相同类型实例化的BlobPtr和相等运算符
friend class BlobPtr<T>;
friend class SharedPtr<T>;
//template<typename X>friend class BlobPtr<T>;
friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
//template<typename X>friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
public:
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
Blob();
Blob(std::initializer_list<T>il);
//模板构造函数
template<typename It>Blob(It b, It e);
size_type size()const { return (*data).size(); }
bool empty()const { return (*data).element_type(); }
void push_back(const T& t) { (*data).push_back(t); }
//移动版本
void push_back(T&& t) { (*data).push_back(std::move(t)); }
void pop_back();
//元素访问
T& back()const;
T& operator[](size_type i);
BlobPtr<T> begin() { return BlobPtr<T>(*this); }
BlobPtr<T> end()
{
auto ret = BlobPtr<T>(*this, (*data).size());
return ret;
}
T& front()const;
private:
SharedPtr<std::vector<T>>data;
//data[i]无效,则抛出msg
void check(size_type i, const std::string& msg)const;
};
template<typename T>
T& Blob<T>::front()const
{
check(0, "front on empty Blob");
return data->front();
}
//check
template<typename T>
void Blob<T>::check(size_type i, const std::string& msg)const
{
if (i >= data->size())
{
throw std::out_of_range(msg);
}
}
//back
template<typename T>
T& Blob<T>::back()const
{
check(0, "back on empty Blob");
return data->back();
}
//下标运算符
template<typename T>
T& Blob<T>::operator[](size_type i)
{
check(i, "subscript out of range");
return (*data)[i];
}
//pop函数
template<typename T>
void Blob<T>::pop_back()
{
check(0, "pop_back on empty Blob");
data->pop_back();
}
//构造函数
template<typename T>
Blob<T>::Blob() :data(MakeShared<std::vector<T>>()) { }
//接受initializer_list的构造函数
template<typename T>
Blob<T>::Blob(std::initializer_list<T>il) : data(MakeShared<std::vector<T>>(il)) { }
//若试图访问一个不存在的元素,BlobPtr抛出一个异常
template<typename T>class BlobPtr {
public:
BlobPtr() :curr(0) { }
BlobPtr(Blob<T>& a, size_t sz = 0) :wptr(a.data), curr(sz) { }
T& operator*()const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
//递增与递减
BlobPtr& operator++();
BlobPtr& operator--();
BlobPtr& operator++(int);
BlobPtr& operator--(int);
T& deref() const;
BlobPtr& incr();
private:
std::shared_ptr<std::vector<T>>check(std::size_t, const std::string&)const;
std::weak_ptr<std::vector<T>>wptr;
std::size_t curr;
};
template<typename T>
T& BlobPtr<T>:: deref()const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
template<typename T>
BlobPtr<T>& BlobPtr<T>::incr()
{
//递增curr,判断curr位于合理位置,不合理位置不递增
check(curr, "incrasement past end of BlobPtr");
++curr;
return *this;
}
template<typename T>
BlobPtr<T>& BlobPtr<T>::operator++(int)
{
BlobPtr ret = *this;
++* this;
return ret;
}
template<typename T>
BlobPtr<T>& BlobPtr<T>::operator--(int)
{
BlobPtr ret = *this;
--* this;
return ret;
}
template<typename T>
BlobPtr<T>& BlobPtr<T>::operator++()
{
check(curr, "increment past end of BlobPtr");
++curr;
return *this;
}
template<typename T>
BlobPtr<T>& BlobPtr<T>::operator--()
{
check(curr, "decrement past begin of BlobPtr");
++curr;
return *this;
}
int main()
{
Blob<int>b1 = { 1,2,3,4,5,6,7,8,9 };
cout << b1.size() << endl;
system("pause");
return 0;
}
结果如下:
练习16.30:
见练习16.29
练习16.31:
shared_ptr是运行时绑定删除器,而unique_ptr则是编译时绑定删除器。unqiue_ptr有两个模板参数,一个是所管理的对象类型,另一个是删除器类型。因此,删除器类型是unique_ptr类型的一部分,在编译时就可知道,删除器可直接保存在unique_ptr对象中。通过这种方式,unique_ptr避免了间接调用删除器的运行时开销,而编译时还可以将自定义的删除器,如DebugDelete编译为内联形式