C++——智能指针unique_ptr的实现
- 起初,我最直观的设计想法,直接设计一个类:包含全部要素(对象,指针计数)。然后提供出去。
class CPoint
{
public:
CPoint(int xVal = , int yVal = ) : x(xVal), y(yVal) {}
int getX() const { return x; }
int getY() const { return y; }
void setX(int xVal) { x = xVal; }
void setY(int yVal) { y = yVal; } private:
int x, y;
}; class CSmartPtr
{
public:
CSmartPtr(CPoint *ptr) : m_pPoint(ptr),m_count() {}
CSmartPtr(const CSmartPtr &sptr) : m_pPoint(sptr.m_pPoint),m_count(sptr.m_count) {} ~CSmartPtr()
{
Release();
}
CPoint* get()
{
return m_pPoint;
}
/*此处不知道如何有效实现,既能提供出去,有把内部清空????*/
CPoint *release()
{
m_count = ;
return m_pPoint;
}
int user_count() { return m_count; }
CPoint &operator*()
{
return *(m_pPoint);
} CPoint *operator->()
{
return m_pPoint;
} private:
void Release()
{
if (m_count-- == )
{
delete m_pPoint;
}
else
{
cout << "引用次数:" << m_count << endl;
}
} int m_count;
CPoint *m_pPoint;
};
但是我实现到release方法的时候,并不能满足需求。因为release方法的要求是,交出对象的控制权,然后智能指针指向null;Releases ownership of its stored pointer, by returning its value and replacing it with a null pointer.这就尴尬了。因此采用了将指针计数和对象单独拿出来的做法,也就是网上其他博客中常见的做法。但我还不是很理解他们那种做法的解释。

代码实现:
class CPoint
{
public:
CPoint(int xVal = , int yVal = ) : x(xVal), y(yVal) {}
int getX() const { return x; }
int getY() const { return y; }
void setX(int xVal) { x = xVal; }
void setY(int yVal) { y = yVal; } private:
int x, y;
};
class CSmartPtr;
/* */
class CCountPtr
{
private:
friend class CSmartPtr;
int m_count;
CPoint *m_pPoint;
CCountPtr(CPoint *ptr):m_pPoint(ptr),m_count(){}
~CCountPtr()
{
m_count=;
}
}; class CSmartPtr
{
public:
CSmartPtr(CPoint *ptr) : m_pCountPtr (new CCountPtr(ptr)){}
CSmartPtr(const CSmartPtr &sptr) : m_pCountPtr(sptr.m_pCountPtr) {}
CSmartPtr& operator=(const CSmartPtr &sptr)
{
(sptr.m_pCountPtr->m_count)++;
minusOne();
m_pCountPtr = sptr.m_pCountPtr;
return *this;
}
~CSmartPtr()
{
minusOne();
}
CPoint *get()
{
return m_pCountPtr->m_pPoint;
}
CPoint *release()
{
CPoint *pRet = m_pCountPtr->m_pPoint;
m_pCountPtr->m_pPoint = nullptr;
m_pCountPtr->m_count = ;
return pRet;
}
/*Destroys the object currently managed by the unique_ptr (if any) and takes ownership of p.*/
void reset(CPoint *pPoint)
{
minusOne();
m_pCountPtr = new CCountPtr(pPoint);
}
void swap(CSmartPtr &x)
{
CPoint *pRet = m_pCountPtr->m_pPoint;
int count = m_pCountPtr->m_count; m_pCountPtr->m_pPoint = x.m_pCountPtr->m_pPoint;
m_pCountPtr->m_count = x.m_pCountPtr->m_count; x.m_pCountPtr->m_pPoint = pRet;
x.m_pCountPtr->m_count = count;
} int user_count(){return m_pCountPtr->m_count; }
CPoint& operator *()
{
return *(m_pCountPtr->m_pPoint);
} CPoint* operator ->()
{
return m_pCountPtr->m_pPoint;
} private:
void minusOne()
{
if (m_pCountPtr->m_count-- == )
{
delete m_pCountPtr;
m_pCountPtr = nullptr;
}
else
{
cout << "引用次数:" << m_pCountPtr->m_count << endl;
}
}
CCountPtr *m_pCountPtr;
}; int main()
{
CPoint *pPoint = new CPoint(,);
{
CSmartPtr sptr1(pPoint);
{
(*sptr1).setX();
cout<<"initial:"<<endl;
cout << "sptr1->getX(): " << sptr1->getX() << endl;
CPoint *pPoint2 = new CPoint(, );
/*测试swap*/
cout << "swap:" << endl;
CPoint *pPoint4 = new CPoint(, );
CSmartPtr sptr2(pPoint4);
sptr1.swap(sptr2);
cout << "sptr1->getX(): " << sptr1->getX() << endl;
cout << "sptr2->getX(): " << sptr2->getX() << endl;
/*测试reset*/
cout << "reset:" << endl;
sptr1.reset(pPoint2);
cout << "sptr1->getX(): " << sptr1->getX() << endl;
/*测试release*/
cout << "release:" << endl;
CPoint *pPoint3 = new CPoint(, );
pPoint3 = sptr1.release();
cout << "pPoint3->getX(): " << pPoint3->getX() << endl;
cout << "sptr1.count: " << sptr1.user_count() << endl;
}
cout<<"sptr1.count: "<< sptr1.user_count()<<endl;
} cout<<"pPoint.getx(): "<<pPoint->getX()<<endl;
system("pause");
return ;
}
2.模板类。改进一下即可。将CPoint换成泛型表达。
template <typename T>
class CSmartPtr; template <typename T>
class CCountPtr
{
private:
friend class CSmartPtr<T>;
int m_count;
T *m_pT;
CCountPtr(T *ptr) : m_pT(ptr), m_count() {}
~CCountPtr(){}
}; template <typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr) : m_pCountPtr (new CCountPtr<T>(ptr)){}
CSmartPtr(const CSmartPtr &sptr) : m_pCountPtr(sptr.m_pCountPtr) {}
CSmartPtr& operator=(const CSmartPtr &sptr)
{
(sptr.m_pCountPtr->m_count)++;
minusOne();
m_pCountPtr = sptr.m_pCountPtr;
return *this;
} ~CSmartPtr()
{
minusOne();
}
T * get()
{
return m_pCountPtr->m_pPoint;
}
T *release()
{
T *pRet = m_pCountPtr->m_pPoint;
m_pCountPtr->m_pPoint = nullptr;
m_pCountPtr->m_count = ;
return pRet;
}
/*Destroys the object currently managed by the unique_ptr (if any) and takes ownership of p.*/
void reset(T *pPoint)
{
minusOne();
m_pCountPtr = new CCountPtr<T>(pPoint);
}
void swap(CSmartPtr &x)
{
T *pRet = m_pCountPtr->m_pPoint;
int count = m_pCountPtr->m_count; m_pCountPtr->m_pPoint = x.m_pCountPtr->m_pPoint;
m_pCountPtr->m_count = x.m_pCountPtr->m_count; x.m_pCountPtr->m_pPoint = pRet;
x.m_pCountPtr->m_count = count;
} int user_count(){return m_pCountPtr->m_count; } T& operator *()
{
return *(m_pCountPtr->m_pT);
} T* operator ->()
{
return m_pCountPtr->m_pT;
} private:
void minusOne()
{
if (m_pCountPtr->m_count-- == )
{
delete m_pCountPtr;
m_pCountPtr = nullptr;
}
else
{
cout << "引用次数:" << m_pCountPtr->m_count << endl;
}
}
CCountPtr<T> *m_pCountPtr;
}; /*这里使用了参数包,我对此不是很熟悉,直接copy的代码*/
template<typename T, typename... Args>
inline CSmartPtr<T>
make_smart(Args&&... args)
{
return CSmartPtr<T>(new T(std::forward<Args>(args)...));
} int main()
{
int b=;
int* a=&b;
{
CSmartPtr<int> sptr1(a);
{
cout << "*sptr1: " << *sptr1 << endl;
CSmartPtr<int> sptr2 = sptr1; cout << "*sptr2: " << *sptr2 << endl; CSmartPtr<int> sptr3 = make_smart<int>();
cout << "*sptr3: " << *sptr3 << endl;
}
cout<<"sptr1.count: "<< sptr1.user_count()<<endl;
} system("pause");
return ;
}
以上为智能指针shared_ptr的实现过程,还是有很多东西要学习的。
以下为参考网站,以至于很多东西都是直接拿过来的,感谢!
https://www.cnblogs.com/QG-whz/p/4777312.html
http://www.cplusplus.com/reference/memory/unique_ptr/unique_ptr/
https://liam.page/2018/01/13/smart-pointer/
C++——智能指针unique_ptr的实现的更多相关文章
- c/c++ 智能指针 unique_ptr 使用
智能指针 unique_ptr 使用 和shared_ptr不同,可以有多个shared_ptr指向同一个内存,只能有1个unique_ptr指向某个内存.因此unique_ptr不支持普通的拷贝和赋 ...
- c++11 智能指针 unique_ptr、shared_ptr与weak_ptr
c++11 智能指针 unique_ptr.shared_ptr与weak_ptr C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer), ...
- C++智能指针 unique_ptr
C++智能指针 unique_ptr unique_ptr 独占所指向的对象, 同一时刻只能有一个 unique_ptr 指向给定对象(通过禁止拷贝语义, 只有移动语义来实现), 定义于 memory ...
- 智能指针unique_ptr的用法
unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...
- C++11 智能指针unique_ptr使用 -- 以排序二叉树为例
用智能指针可以简化内存管理.以树为例,如果用普通指针,通常是在插入新节点时用new,在析构函数中调用delete:但有了unique_ptr类型的智能指针,就不需要在析构函数中delete了,因为当u ...
- 智能指针unique_ptr
转自:https://www.cnblogs.com/DswCnblog/p/5628195.html 成员函数 (1) get 获得内部对象的指针, 由于已经重载了()方法, 因此和直接使用对象是一 ...
- 智能指针 unique_ptr
unique_ptr 不共享它的指针.它无法复制到其他 unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库 (STL) 算法. 1.不能进行复制构造和赋值操作(unique ...
- 智能指针unique_ptr记录
unique_ptr 对对象独有管理,无法复制,共享,值传递,可以使用move语义来转移控制权. std::default_delete<int> d; std::unique_ptr&l ...
- 第20课 unique_ptr独占型智能指针
一. unique_ptr的基本用法 (一)初始化方式 1. 直接初始化:unique<T> myPtr(new T); //ok.但不能通过隐式转换来构造,如unique<T&g ...
随机推荐
- 初识html与css
---恢复内容开始--- PS应用量尺寸w.h- 操作方式: 窗口,信息,右上角面板选项,标尺单位,像素切图- 操作方式: 切片工具, 文件 ,另存为web所有格式,jpeg,存储,切片:选中的切片, ...
- java代码生成json数据
https://www.cnblogs.com/libo0125ok/p/7905665.html
- (2018 Multi-University Training Contest 3)Problem L. Visual Cube
//题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6330//题目大意:按照一定格式画出一个 a×b×c 的长方体. #include <b ...
- Ruby中puts,print,p的区别
如果字符串的行尾没有包含换行符,puts就会添加一个,但print不会: print会精确打印内容并让光标留在末尾(在某些系统平台,在程序输出的末尾会自动换行): p会输出一个审查字符串,它通常会包含 ...
- js隐藏字符串中间部分
在进行web前端页面开发中,有时需要从后台获取用户数据来显示在前台页面,但是考虑到用户信息安全的问题,就需要对这些信息进行处理,使其不完全显示出来,例如姓名,两个字的显示姓,名字用*代替,电话前三位和 ...
- Openflow协议详解
http://www.h3c.com/cn/d_201811/1131080_30005_0.htm# 1 OpenFlow背景 转发和控制分离是SDN网络的本质特点之一 .在SDN网络架构中,控制平 ...
- QA Report
- 小程序 movable-area 实现悬浮窗效果
最近做一个小程序 实现页面内悬浮窗的效果 给自己制定两个方案: 1.通过一个自定义的组件,通过触摸事件进行实现: 2.使用微信的movable移动组件实现: 第一种方案: 结果:实现了 悬浮窗和自动靠 ...
- Netty 服务端启动过程
在 Netty 中创建 1 个 NioServerSocketChannel 在指定的端口监听客户端连接,这个过程主要有以下 个步骤: 创建 NioServerSocketChannel 初始化并注 ...
- 三、后门的编写和 ShellCode 的提取
第三章.后门的编写和 ShellCode 的提取 (一)IP 和 Socket 编程初步 NOTES: 1.Windows 下网络通信编程的几种方式 第一种是基于 NetBIOS 的网络编程,这种方法 ...