昨天和前公司两个同事喝了点小酒,本以为,10个月没有喝酒了,这次再喝应该会很香,但是实际确实难以下咽,和第一次喝酒的感觉一样,这玩意这么难喝,真是花钱找难受。那么编程是不是也是一样了,我们以为搁置了一段时间在搞会很香,其实和刚开始一样呢?一切都得重头来了?

最近一直准备搞一个Qt 和vtk结合的东西,发现了C++ 、 Qt 、vtk,每家都有自己的使能指针实现,那么,Qt 和vtk 为什么不用C++原生的智能指针,而是要费气吧咧的自己实现一个那,抱着这个想法想看看他们三者的智能指针到底有什么区别呢。有用自己本身技能太弱,基本只能是抄代码,凑乎着看,目前只能写这么点东西,后面应该会再搞一个吧,先水一篇。

真正的内容,要看参考链接里面大神们写的东西,目前我的感觉就是我很想向大神们一样写出有价值的东西来,但是太菜了,输出不了,加油吧。



[TOC]



关键字:​C++​​​、​​智能指针​​​、​​shared_ptr​​​、​​unipue_ptr​​​、​​应用计数器​


为什么要搞一个智能指针

​ 一个程序,除了有静态内存和栈内存外,每个程序还有一个内存池,这部分被称为堆或者称为自由空间,程序用堆来存储动态奉陪的对象即那些在程序运行时分配的对象,当动态对象不再被使用时,就需要我们的代码必须显式的销毁他们。由于C++ 语言没有自动内存回收机制,我们每次​​new​​​出来的内容都要手动​​delete​​​,如果我们在开发中忘记了,或者由于流程复杂导致最终没有​​delete​​​,或者由于程序异常,导致没有程序没有执行​​delete​​操作,这就容易出现内存泄露的情况。使用智能指针便可以有效的缓解这类问题。智能指针就是是为了更加安全(容易)的使用动态内存而引入的概念。智能指针的行为类似常规指针,重要的叙别是它负责自动释放所指向的对象。标准库提供两种智能指针,区别在于管理底层指针的方法不同,​​shared_ptr​​​允许多个指针指向同一个对象,​​unipue_ptr​​则独占所指向的对象。标准库还定义了一种名为​​weak_ptr​​​的伴随类,他是一种弱引用,指向​​shared_ptr​​所管理的对象,这三种智能指针都定义在memory头文件中。

实现代码

抄了一段代码

#include <iostream>
#include <memory>
using namespace std;
template <typename T>
class SmartPointer {
private:
T* _ptr;
size_t* _count;
public:
SmartPointer(T* ptr = nullptr):_ptr(ptr)
{
if (_ptr)
{
_count = new size_t(1);
}
else
{
_count = new size_t(0);
}
}

SmartPointer(const SmartPointer& ptr)
{
if (this != &ptr)
{
this->_ptr = ptr._ptr;
this->_count = ptr._count;
(*this->_count)++;
}
}

SmartPointer& operator= (const SmartPointer& ptr)
{
if (this->_ptr == ptr._ptr)
return *this;
if (this->_ptr)
{
(*this->_count)--;

if (this->_count == 0)
{
delete this->_ptr;
delete this->_count;
}
}

this->_ptr = ptr._ptr;
this->_count = ptr._count;
(*this->_count)++;
return *this;
}

T& operator* ()
{
static_assert(this->_ptr == nullptr);
return *(this->ptr);
}

T* operator->()
{
static_assert(this->_ptr == nullptr);
return this->_ptr;
}

~SmartPointer()
{
(*this->_count)--;
if (*this->_count == 0)
{
delete this->_ptr;
delete this->_count;
}
}

size_t use_count()
{
return *this->_count;
}

};

int main()
{
SmartPointer<int> sp(new int(10));
SmartPointer<int> sp2(sp);
SmartPointer<int> sp3(new int(20));

sp2 = sp3;

cout << sp.use_count() << endl;
cout << sp3.use_count() << endl;

return 0;
}

参考链接