智能指针的简单实现及两种误用方式
来源:互联网 发布:单片机电机驱动 编辑:程序博客网 时间:2024/04/29 19:30
最近在自己写智能指针的时候,遇到了一些小的疑惑,也纠正了之前的一些理解上的偏差。
首先是最简单的智能指针的一个实现:
template<class T>class SmartPointer{private:T* ptr;public:SmartPointer(T* p) :ptr(p){} //构造函数T& operator*(){ //重载*操作符return *ptr; }T* operator->(){ //重载->操作符return ptr;}~SmartPointer(){ //析构函数delete ptr;}};这与auto_ptr类似,可以完成自动释放内存的功能,但一旦程序员使用了如下的方式:
class A{};SmartPointer<A> ptr(new A);SmartPointer<A> ptr1=ptr;会导致程序崩溃,因为ptr和ptr1两个智能指针会重复delete源指针,所以stl里有了shared_ptr。
下面看一下加入了引用计数的智能指针的实现:
template<class T>class SharedPointer{public:explicit SharedPointer(T* p) :ptr(p),count(NULL){ //构造函数,不允许隐式转换count = new size_t(1);}SharedPointer(const SharedPointer& orig):ptr(orig.ptr),count(orig.count){ //复制构造函数++*count;}SharedPointer& operator=(const SharedPointer& rhs){ //赋值构造函数++*(rhs.count);if (--*count == 0){ //防止自我赋值时误删delete ptr;}ptr = rhs.ptr;count = rhs.count;return *this;}~SharedPointer(){ //析构函数if (--*count == 0)delete ptr;}T& operator*(){ return *ptr;}T* operator->(){return ptr;}T* getOriPtr(){return ptr;}private:T *ptr;size_t* count;};
在SharedPointer里添加了一个指向计数的指针count,每当智能指针被复制构造或者赋值构造的时候,count指向的值都会自增,当count指向的值为0时,智能指针的析构函数才会调用delete释放原始指针的内存。
这里发现了两种可能导致误用的例子,是我在实际实用中发生的。
1.让智能指针指向栈区:
class A{};A a;SharedPointer<A> ptr(&a);这样的使用,编译器将不会报错,但是由于a是存储在栈区的对象,在进程结束前将自动调用析构函数,而我们的智能指针ptr会对栈区使用delete,导致程序崩溃。
2.用同一个源指针构造两个不同的智能指针:
class A{};A* p=new A;SharedPointer<A> ptr(p);SharedPointer<A> ptr1(p);这样的使用,将导致指针p被两次调用delete;原因是count指向的内存是在构造函数中分配的,ptr和ptr1都是通过构造函数构造出来的,其count分别指向两个不同地址,其值都为1,在ptr析构时,ptr的count指向的值变为0,发生delete p;接下来在ptr1析构时,ptr1的count指向的值变为0,再发生delete p;这样就导致了程序崩溃。
所以在使用智能指针时,应该统一采用如下使用方式:
class A{};SharedPointer<A> ptr(new A);SharedPointer<A> ptr1(new A);这样就可以保证不会出现如上两种错误。
1 0
- 智能指针的简单实现及两种误用方式
- 智能指针的简单实现
- 智能指针的简单实现
- 智能指针的简单实现
- 智能指针的简单实现
- C++ 引用计数技术及智能指针的简单实现
- C++ 引用计数技术及智能指针的简单实现
- C++ 引用计数技术及智能指针的简单实现
- C++ 引用计数技术及智能指针的简单实现
- C++ 引用计数技术及智能指针的简单实现
- C++引用计数技术及智能指针的简单实现
- C++ 引用计数技术及智能指针的简单实现
- 智能指针的两种实现(引用计数)
- 智能指针实现方式
- 智能指针原理,并实现一个简单的智能指针
- 智能指针的原理及简单模拟
- 一种智能指针的实现方式
- 简单实现智能指针
- 关于异步,同步,阻塞与非阻塞
- MySQL已有column值为NULL,修改列属性为NOT NULL报1138错误
- Java中的transient,volatile和strictfp关键字
- 第九周项目一-深体验复制(2)
- HDU 开门人和关门人
- 智能指针的简单实现及两种误用方式
- linux下搭建java服务器环境
- Android学习资料收集
- 并查集(Union-Find)算法介绍
- JVM调优总结(一)-- 一些概念
- 牛客网刷题总结
- [C++]polymorphic and OOP design pattern Abstract Factory(抽象工厂模式)
- 可控硅BT136典型应用电路
- Lua核心编程之基础