文章目录
- unique_ptr 智能指针的实现
- shared_ptr 智能指针的实现
- 指针类型转换
unique_ptr 智能指针的实现
一个对象只能被单个unique_ptr 所拥有。
#include <iostream>
using namespace std;
/*增加模板类型,保证智能指针的类型是由传入的类型决定的*/
template <typename T>
class smart_ptr {
public:
explicit smart_ptr(T *ptr = nullptr): ptr_(ptr){}
/*移动构造函数,当前智能指针仅能被一个对象引用*/
smart_ptr(smart_ptr&& other) {ptr_ = other.release();}
/*如果我们想要消除移动构造和拷贝构造,只需要将其 构造标记为delete*/
//smart_ptr(const smart_ptr&) = delete;
//smart_ptr& operator=(const smart_ptr&) = delete;
/*在构造参数时直接生成新的智能指针,从而不再需要在函数体中构造临时对象,当前支持移动构造进行函数对象的构造。*/
smart_ptr& operator=(smart_ptr rhs) {
rhs.swap(*this);
return *this;
}
T* release() {
T* ptr = ptr_;
ptr_ = nullptr;
return ptr;
}
void swap(smart_ptr& rhs) {
using std::swap;//标准模板库的交换函数
swap(rhs.ptr_,ptr_);
}
~smart_ptr(){delete ptr_;}
T* get() const{ return ptr_;}
/*指针的特性,可以通过*解引用访问 */
T& operator*() const{return *ptr_;}
/*指针的特性,可以通过-> 访问指针的地址内容*/
T* operator->() const{return ptr_;}
/*重载bool运算符,能够让smart_ptr像指针一样用在布尔表达式中*/
operator bool() const{return ptr_;}
private:
T* ptr_;
};
class Shape{
public:
virtual void create_shape() = 0;
virtual ~Shape(){}
};
class Circle: public Shape{
public:
Circle(){cout << "Circle::Circle()" << endl;}
void create_shape(){cout << "create shape: Circle" << endl;}
~Circle(){cout << "Circle::delete()" << endl;}
};
class Triangle: public Shape{
public:
Triangle(){cout << "Triangle::Tirangle()" << endl;}
void create_shape(){cout << "create shape: Triangle" << endl;}
~Triangle(){cout << "Triangle::delete()" << endl;}
};
int main()
{
smart_ptr<Shape> ptr1(new Circle);
smart_ptr<Shape> ptr2(nullptr);
smart_ptr<Shape> ptr3 ;
//ptr3 = ptr1; //编译报错,赋值需要一个对象(而非引用),因而进入执行之前需要引发一个构造,但是此时没有可用的构造函数
ptr3 = std::move(ptr2); // 编译正常,支持移动构造
return 0;
}
shared_ptr 智能指针的实现
多个shared_ptr可以共享同一个对象,当他们全部失效的时候,这个对象才会被删除。
此时对shared_ptr的需求是共享 同一个对象时也需要共享同一个计数,当最后一个指向对象(和共享计数)的shared_ptr析构时,它需要删除对象和共享计数。
在以上unique_ptr的实现基础上增加引用计数相关的操作,实现如下:
#include <iostream>
using namespace std;
/*增加一个引用计数类,来记录当前对象被智能指针引用的次数*/
class shared_count{
public:
shared_count():count_(1) {}
void add_count(){
++count_;
}
long reduce_count(){
return --count_;
}
long get_count() {
return count_;
}
private:
long count_;
};
/*增加类模板,保证智能指针的类型是由传入的类型决定的*/
template <typename T>
class smart_ptr {
public:
explicit smart_ptr(T *ptr = nullptr): ptr_(ptr){
if(ptr) {
shared_count_ = new shared_count();
}
}
/*移动构造函数,当前智能指针仅能被一个对象引用,同时不进行引用计数的自加*/
template <typename U>
smart_ptr(smart_ptr<U>&& other) {
ptr_ = other.release();
if(ptr_) {
shared_count_ = other.shared_count_;
other.ptr_ = nullptr;
}
}
/*拷贝构造函数,支持子类对象向父类对象的拷贝*/
template <typename U>
smart_ptr(const smart_ptr<U>& other) {
ptr_ = other.ptr_;
if(ptr_) {
other.shared_count_ -> add_count();
shared_count_ = other.shared_count_;
}
}
/*同类型对象的拷贝构造函数*/
smart_ptr(smart_ptr & other) {
ptr_ = other.ptr_;
if(ptr_) {
other.shared_count_ -> add_count();
shared_count_ = other.shared_count_;
}
}
/*在构造参数时直接生成新的智能指针,从而不再需要在函数体中构造临时对象,当前支持移动构造进行函数对象的构造。*/
smart_ptr& operator=(smart_ptr rhs) {
rhs.swap(*this);
return *this;
}
T* release() {
T* ptr = ptr_;
ptr_ = nullptr;
return ptr;
}
void swap(smart_ptr& rhs) {
using std::swap;
swap(rhs.ptr_,ptr_);
swap(rhs.shared_count_,shared_count_);
}
long use_count() const {
if(ptr_) {
return shared_count_->get_count();
} else {
return 0;
}
}
~smart_ptr(){
// cout << "smart_ptr::delete count is " << shared_count_ -> get_count() << endl;
if(ptr_ && !shared_count_ -> reduce_count()){
delete ptr_;
delete shared_count_;
}
}
T* get() const{ return ptr_;}
T& operator*() const{return *ptr_;}
T* operator->() const{return ptr_;}
operator bool() const{return ptr_;}
private:
T* ptr_;
shared_count* shared_count_;//统计对象引用计数的类
};
class Shape{
public:
virtual void create_shape() = 0;
virtual ~Shape(){}
};
class Circle: public Shape{
public:
Circle(){cout << "Circle::Circle()" << endl;}
void create_shape(){cout << "create shape: Circle" << endl;}
~Circle(){cout << "Circle::delete()" << endl;}
};
class Triangle: public Shape{
public:
Triangle(){cout << "Triangle::Tirangle()" << endl;}
void create_shape(){cout << "create shape: Triangle" << endl;}
~Triangle(){cout << "Triangle::delete()" << endl;}
};
int main()
{
smart_ptr<Shape> ptr1(new Circle);
cout << "use count of ptr1 is: " << ptr1.use_count() << endl;
smart_ptr<Shape> ptr2;
cout << "use count of ptr2 was: " << ptr2.use_count() << endl;
//ptr2 = std::move(ptr1); // 移动拷贝构造,不进行计数增加(可查看以上的实现)
ptr2 = ptr1; //普通的拷贝构造,支持多个指针共享同一个对象,则对应智能指针的共享计数增加
cout << "use count of ptr2 is now: " << ptr2.use_count() << endl;
if(ptr1) {
cout << "ptr1 is not empty " << endl;
}
return 0;
}
输出如下:
Circle::Circle()
use count of ptr1 is: 1
use count of ptr2 was: 0
use count of ptr2 is now: 2
Circle::delete()
指针类型转换
C++已有的强制类型转换有如下几种:
- static_cast 用于类层次结构中基类和派生类之间指针或引用的转换
- reinterpret_cast 改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型
- const_cast 用于强制去掉不能被修改的常数特性
- dynamic_cast dynamic_cast是运行时处理的,运行时要进行类型检查。
智能指针需要实现类似的函数模板,想要达到以上对应的强制类型转换的功能,我们需要增加构造函数,且允许在对智能指针内部的指针对象赋值时,使用一个现有的智能指针的共享计数。如下所示:
template <typename U>
smart_ptr(const smart_ptr<U> &other, T* ptr) { //拷贝构造时,使用T* ptr进行类型转换
_ptr = ptr;
if(_ptr) {
other.shared_count_ -> add_count();
shared_count_ = other.shared_count_;
}
}
根据以上代码,实现
dynamic_pointer_cast
template <typename T, typename U>
smart_ptr <T> dynamic_pointer_cast(
const smart_ptr<U> &other) {
T *ptr = dynamic_cast<T*> (other.get());
return smart_ptr<T> (other,ptr);
}
使用方式如下:
template <typename T, typename U>
smart_ptr <T> static_pointer_cast(
const smart_ptr<U> &other) {
T *ptr = static_cast<T*> (other.get());
return smart_ptr<T> (other,ptr);
}
template <typename T, typename U>
smart_ptr <T> reinterpret_pointer_cast(
const smart_ptr<U> &other) {
T *ptr = reinterpret_cast<T*> (other.get());
return smart_ptr<T> (other,ptr);
}
template <typename T, typename U>
smart_ptr <T> const_pointer_cast(
const smart_ptr<U> &other) {
T *ptr = const_cast<T*> (other.get());
return smart_ptr<T> (other,ptr);
}