C++智能指针
来源:互联网 发布:淘宝买家贷款操作流程 编辑:程序博客网 时间:2024/06/07 07:20
内存泄露一直是C++程序员头疼的问题。下面就简单理解下C++智能指针。
智能指针 是存储指向动态分配对象指针的类。 目的是能够自动正确的销毁内存,防止内存泄露。
通
用的实现技术是使用引用计数(reference count),将一个计数器与类指向的对象相关联。引用计数跟踪该类有多少个对象共享同一指针
创建一个类的对象时, 初始化指针并且将引用计数置为1;
当一个对象作为另一个对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相关的引用计数。
对一个对象进行赋值时,赋值操作符减少左操作数的引用计数,如引用计数为0, 删除对象, 释放对象指向的内存
并增加右操作符所指对象的引用计数。
调用析构函数时,减少引用计数, 如果引用计数为0, 删除对象, 释放对象指向的内存
设计思路:
由于需要一个引用计数和一个指针动态内存,将他们封装为一个类
定义一个Uptr类,成员函数为引用计数和指针。 实现构造函数, 析构函数, 拷贝构造函数和赋值运算符重载。
设计一个管理类HasPtr, 管理这个Uptr类的引用计数和指针,将HasPtr声明为Uptr类的友元类。即只有HasPtr可以访问为Uptr类。
用2个类实现的好处是 解耦合,增加智能指针的可扩展性,引用计数和指针是不变的, 智能指针的管理是可变的, 将可变的和不变的逻辑分离出来。
class Uptr{/*Uptr has private member, only HasPtr class can access it*/friend class HasPtr;private:Uptr(int *p):m_ptr(p),m_useNum(1) {cout<< "Uptr constructor called" << endl;}~Uptr() {if(NULL!=m_ptr) {delete []m_ptr; m_ptr = NULL;}cout << "Uptr destructor called" << endl;}Uptr(const Uptr& o){m_ptr = o.ptr;}Uptr& operator=(const Uptr& o){if (&o == this){return;}if (m_ptr != NULL){delete []m_ptr;}//shallow copym_ptr = o.m_ptr;}private:int* m_ptr;int m_useNum;};
下面是实现HasPtr 管理类
class HasPtr{public:HasPtr(int *p):m_ptr(new Uptr(p)) {cout << "HasPtr constructor called!" << "use=" <<m_ptr->m_useNum << endl;}HasPtr(const HasPtr& o){m_ptr = o.m_ptr;/*add the useNum when copy*/++m_ptr->m_useNum;cout << "HasPtr copy constructor called!" << "use=" <<m_ptr->m_useNum << endl;}HasPtr& operator=(const HasPtr& o);~HasPtr(){/*delete the useNum when destructor*/if (--m_ptr->m_useNum == 0){delete m_ptr;}cout << "HasPtr distructor called!" << "use=" <<m_ptr->m_useNum << endl;}void set_ptr(int *p){if (p == NULL){delete m_ptr;}m_ptr->m_ptr = p;}int* get_ptr() const{return m_ptr->m_ptr;}private:Uptr* m_ptr;};HasPtr& HasPtr::operator=(const HasPtr& o){cout << "operator= called" << endl;if (&o == this){return *this;}++o.m_ptr->m_useNum;/*release the memory if it is neccessary*/if (--m_ptr->m_useNum == 0){delete m_ptr;}m_ptr = o.m_ptr;return *this;}
其中有几个需要注意的地方:
赋值运算符重载要考虑 自己赋值给自己的特殊情况, 一个智能指针类对象给另一个智能指针类对象赋值时, 赋值操作符减少左操作数的引用计数,如引用计数为0, 删除对象, 释放对象指向的内存并增加右操作符所指对象的引用计数。
全部程序:
/**describe: realize smart point, keep improve*/#include <iostream>#include <string.h>using namespace std;/*use two class realize the function. high cohesion and low coupling*/class Uptr{/*Uptr has private member, only HasPtr class can access it*/friend class HasPtr;private:Uptr(int *p):m_ptr(p),m_useNum(1) {cout<< "Uptr constructor called" << endl;}~Uptr() {if(NULL!=m_ptr) {delete []m_ptr; m_ptr = NULL;}cout << "Uptr destructor called" << endl;}Uptr(const Uptr& o){m_ptr = o.ptr;}Uptr& operator=(const Uptr& o){if (&o == this){return;}if (m_ptr != NULL){delete []m_ptr;}//shallow copym_ptr = o.m_ptr;}private:int* m_ptr;int m_useNum;};class HasPtr{public:HasPtr(int *p):m_ptr(new Uptr(p)) {cout << "HasPtr constructor called!" << "use=" <<m_ptr->m_useNum << endl;}HasPtr(const HasPtr& o){m_ptr = o.m_ptr;/*add the useNum when copy*/++m_ptr->m_useNum;cout << "HasPtr copy constructor called!" << "use=" <<m_ptr->m_useNum << endl;}HasPtr& operator=(const HasPtr& o);~HasPtr(){/*delete the useNum when destructor*/if (--m_ptr->m_useNum == 0){delete m_ptr;}cout << "HasPtr distructor called!" << "use=" <<m_ptr->m_useNum << endl;}void set_ptr(int *p){if (p == NULL){delete m_ptr;}m_ptr->m_ptr = p;}int* get_ptr() const{return m_ptr->m_ptr;}private:Uptr* m_ptr;};HasPtr& HasPtr::operator=(const HasPtr& o){cout << "operator= called" << endl;if (&o == this){return *this;}++o.m_ptr->m_useNum;/*release the memory if it is neccessary*/if (--m_ptr->m_useNum == 0){delete m_ptr;}m_ptr = o.m_ptr;return *this;}/*for test*/void test_func(){int* pValue = new int(10);int* pValue1 = new int(20);if (NULL == pValue){return;}HasPtr ptr1(pValue);HasPtr ptr2(ptr1);HasPtr ptr3 = ptr1;HasPtr ptr4(pValue1);ptr4 = ptr1;cout << endl;}int main(int argc, char** argv){test_func();return 0;}
运行结果
- c++:智能指针
- C++:智能指针
- 【C++】智能指针
- 【C++】智能指针
- C++PJ智能指针
- 【c++】智能指针
- 【C++】智能指针auto_ptr
- C++,智能指针
- C++,boost智能指针
- 智能指针模拟C
- [C++]智能指针
- 【C++】 浅析智能指针
- C++_智能指针
- C++:初识智能指针
- C++::智能指针
- 【C++】智能指针
- c智能指针:unique_ptr
- 【C++】智能指针
- Unity 墙遮挡人物时变为半透明
- 大数的阶乘
- Goahead 在Chrome跳转top.location.href 导致卡死问题
- 【Ogre开发】之一:Ogre sdk的安装以及示例代码的编译和运行
- UNIX环境高级编程——Linux终端设备详解
- C++智能指针
- CentOS下lvm分区简介
- HDU 1104题Remainder(bfs)
- GSON学习-台风路径json解析
- RCP获取插件目录中图像文件
- 位运算 进制转换
- JavaBean
- Android知识点textview加横线的属性
- 黑马程序员---面向对象学习