引用计数
来源:互联网 发布:linux查询arp 编辑:程序博客网 时间:2024/05/16 14:31
当多个指针指向同一个对象,其中一个指针delete后,剩下的指针便成了野指针,浪费内存。
例如:
int *p = new int(3);int *p1 = p;int *p2 = p1;cout << *p1 << " " << *p2 << endl;delete p;cout << *p1 << " " << *p2 << endl;
因此,我们引入引用计数,我个人理解原理如此:设初始对象为t1,计数为1,对象t2指向t1,则t1计数+1,代表有两个对象指向该内存,而t2则-1,因为t2指向t1,若t2=0,则对t2进行销毁。
代码实现:
计数类实现
class count{template<typename T>friend class smart_ptr<T>; //智能指针类模板,用于判断是否销毁对象private:int *c;public:count():c(new int(1));count(count&r)//新对象一开始便指向已有对象,即直接调用复制构造函数{ c=r.c; ++*r.c;}count &operator =(count &r)//已存在对象t1指向已存在对象t2,t1,-1;t2,+1.{ if(--*c==0) delete c; c=r.c; r.c++;}bool selfcopy(count &r)//用于接下来smart_ptr赋值重载判断.{ ++*r.c; if(--*c==0) { deleter c; c=r.c; return true; } c=r.c return false;}bool only()//用于smart_ptr类析构判断。{ if(*c==1) return true; return false;}~count(){ if(--*c==0) //多个对象指向一个块内存,每个对象取消指向时调用析构对计数进行--,等于0时便销毁内存。 delete c;}};
智能指针类
使用模板,体现出泛型编程的好处,能够用于其他类,而不是仅仅一个类。
template<typename T>class smart_ptr {private: T *point; Count count;public: smart_ptr() : point(new T) {} smart_ptr(const T &p) : point(new T(p)) {} smart_ptr(const smart_ptr &sp) : point(sp.point),count(sp.count) {} smart_ptr &operator =(const smart_ptr &p) { if (count.selfcopy(p.count)) { //throw "error"; delete point; } //point = new T; point = p.point; return *this; } T* get()//通过该函数获得使用该模板的类的对象指针,用于访问该类的公有成员。 { return point; } ~smart_ptr() { if (count.isemtpy()) delete point; } };
可以写一个类用于测试,必须写复制构造函数,不重载赋值运算,不运用智能指针模板,多个对象指向同一个对象,被指向对象销毁时,编译器会报内存错误,运用模板后便可以达到销毁野对象的功能。
若想修改使用模板类的类的私有成员,且想让指向该类生成的对象,不会因为修改一个而其他对象的值都会变为同一个,即:
class A{private:int *x;public:A(int n=10){ x=new int[n];}void setx(int c);.......}main(){ smart_ptr<A>t(A()); smart_ptr<A>t1=t; t.get()->setx(5); t1.get()->setx(6); //结果将全是6,因为指针都是指向同一个内存块,要是想不牵一发而动全身,则需要开辟新内存}想给指针开辟新内存,则在smart_ptr类中添加一个函数T* set();T* set(){ if(count.only())//仅有一个时直接返回该指针 return point; point=new T(*(this->point));//给调用set()的对象开辟内存,关于为何是*(this->point),因为this为调用该函数对象指针,而point为使用模板类型T的指针,则*(this->point)为T类型对象。 return point;}则使用set()获取指针调用上述A类中的setx(n)可以修改值,为指向同一对象的其他调用set的对象开辟新内存。
0 0
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 引用计数
- 求最大公约数
- 查看Mysql执行计划
- Spring父子容器加载过程描述
- 深度学习 之 keras
- Java冒泡排序
- 引用计数
- nagios监控mysql数据库性能
- 音乐播放器(iOS完整复杂版)
- iBET Malaysia Casino Sport Books Rebate 0.35% Bonus(malaysia online casino, rebate 0.35%, rebate bon
- cocos2dx apk 打包
- CSS Border(边框)
- leetcode Unique Substrings in Wraparound String
- es6 中的默认参数
- Android ANR