1. 起初,我最直观的设计想法,直接设计一个类:包含全部要素(对象,指针计数)。然后提供出去。
 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的实现的更多相关文章

  1. c/c++ 智能指针 unique_ptr 使用

    智能指针 unique_ptr 使用 和shared_ptr不同,可以有多个shared_ptr指向同一个内存,只能有1个unique_ptr指向某个内存.因此unique_ptr不支持普通的拷贝和赋 ...

  2. 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), ...

  3. C++智能指针 unique_ptr

    C++智能指针 unique_ptr unique_ptr 独占所指向的对象, 同一时刻只能有一个 unique_ptr 指向给定对象(通过禁止拷贝语义, 只有移动语义来实现), 定义于 memory ...

  4. 智能指针unique_ptr的用法

    unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...

  5. C++11 智能指针unique_ptr使用 -- 以排序二叉树为例

    用智能指针可以简化内存管理.以树为例,如果用普通指针,通常是在插入新节点时用new,在析构函数中调用delete:但有了unique_ptr类型的智能指针,就不需要在析构函数中delete了,因为当u ...

  6. 智能指针unique_ptr

    转自:https://www.cnblogs.com/DswCnblog/p/5628195.html 成员函数 (1) get 获得内部对象的指针, 由于已经重载了()方法, 因此和直接使用对象是一 ...

  7. 智能指针 unique_ptr

    unique_ptr 不共享它的指针.它无法复制到其他 unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库 (STL) 算法. 1.不能进行复制构造和赋值操作(unique ...

  8. 智能指针unique_ptr记录

    unique_ptr 对对象独有管理,无法复制,共享,值传递,可以使用move语义来转移控制权. std::default_delete<int> d; std::unique_ptr&l ...

  9. 第20课 unique_ptr独占型智能指针

    一. unique_ptr的基本用法 (一)初始化方式 1. 直接初始化:unique<T> myPtr(new T);  //ok.但不能通过隐式转换来构造,如unique<T&g ...

随机推荐

  1. C语言作业(心理魔术)

    #include "stdafx.h" #include "stdio.h" #include "stdlib.h" #include &q ...

  2. tar: Exiting with failure status due to previous errors

    发生在tar压缩或者解压缩的过程中,原因是压缩包在建立的时候是用了sudo的,所以你解压的时候也要加上sudo,问题就很好解决了的

  3. 常用MySQL操作(一)

    第二十四次课 常用MySQL操作(一) 目录 一.设置更改root密码 二.连接mysql 三.mysql常用命令 四.mysql用户管理 五.常用sql语句 六.mysql数据库备份恢复 七.扩展 ...

  4. 根据图片URL获取图片的尺寸【Swift语言实现】

    import UIKit extension UIImage { /// 获取网络图片尺寸 /// /// - Parameter url: 网络图片链接 /// - Returns: 图片尺寸siz ...

  5. QT_REQUIER_CONFIG

    在qglobal.h中,定义了很多宏.下面这个QT_REQUIER_CONFIG,展开成: #define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(Q ...

  6. python模块之json_pickle_shelve

    序列化:明显是json重要,并且应用场景多. #!/usr/bin/env python # coding:utf-8 import json ## 非常重要的模块,用于不同种编程语言间交换数据. d ...

  7. python小白的自述

    python语言作为目前受用面比较广泛的一种语言,具有简单易学,功能强大的特点.初次接触python完全是由于好奇心,正是因为python的出现,才让我觉得编程不是那么的神秘了.不过作为一个编程小白来 ...

  8. 二进制32位转十进制int

    public class BinaryToDecimal { public static int BinaryToDecimal(int binaryNumber){ int decimal = 0; ...

  9. JavaApi

    #####indexof() package day07Test;/** * 统计字符在句子中出现的次数 * @author gengyantao * */public class Demo1 { p ...

  10. 前端开发:一个开源、简单易用的jQuery表格插件(DataTables)

    DataTables是一个基于jQuery库的开源(MIT协议)表格插件,支持添加.排序.分页.搜索.过滤等功能,使用简单.广受欢迎,能够与主流前端UI整合(如bootstrap.jQuery UI等 ...