C++中的智能指针
来源:互联网 发布:java 怎么用md5 编辑:程序博客网 时间:2024/04/30 03:58
当设计含有指针的类时,应特别小心。因为指针指向的对象通常不包含在类的对象中,当类对象进行复制时,默认复制构造函数通常是浅拷贝(bitwise copy),只是拷贝了指针的值,这是两个指针指向同一个对象。通过其中一个指针就可以改变对象的值,也可以释放指针指向的对象;这时候另一个指针并不知情。引用C++ Primer的例子
- class HasPtr{
- public:
- HasPtr(int *p, int i):ptr(p),val(i){}
- //获取成员变量的接口
- int *get_ptr()const { return ptr;}
- int get_int const {return val;}
- //设置成员变量的接口
- void set_per(int *p){ptr=p;}
- void set_int(int i){val=i;}
- int get_ptr_val()const {return *ptr;}
- int set_ptr_val(int val)const {*prt=val;}//指针的值没变,所以可以为const
- private:
- int *ptr;
- int val;
- }
- int *ip=new int(42);
- HasPtr prt1(ip,42);
- HasPtr ptr2(ptr1);//bitwise copy
为了避免类似的事情发生,C++中给我们提供了智能指针。智能指针的本质是使用一个类来管理指针。在这个类里面加了一个变量--引用计数,记录与指针对象关联的类的个数。只有当引用计数为零时,才可以释放指针指向的对象。智能指针的行为要和普通指针一样。但是智能指针多了引用计数,当引用指针类的个数发现变化时(比如复制构造函数和复制操作符),引用计数要体现出这样变换。例如,在复制构造函数中,引用计数应加1。而在赋值操作符(重载)中,左操作数使用的智能指针引用计数减1 ,而右操作数使用的智能指针引用计数加1。下一个问题就是要把这个引用计数放到哪里?可以放到类HasPtr中吗?如果放到HasPtr中
class HasPtr{
……
private:
int *ptr;int val;
size_t use;//引用计数
}
这样每个对象中就会有引用计数,当我们更新引用计数时,要更新每个对象中的use值,实在难以实现。但是真的不能放到HasPtr中吗?只要确保每个对象都能知道引用计数的值,有能确保引用计数容易更新,就可以。方法是使用指针(指针型句柄就是这样做的)。
- class HasPtr{
- ……
- private:
- int *ptr;
- int val;
- size_t *use;//引用计数
- }
- class U_Ptr{
- friend class HasPtr;
- int *ip;
- size_t use;
- U_Ptr(int *P):ip(p),use(1){}
- ~U_Ptr(){ delete ip;}
- }
使用智能指针类,要像使用普通指针一样,所以要重新设计HasPtr类
- class HasPtr{
- public:
- HasPtr(int *p, int i):ptr(new U_Ptr(p)),val(i){}
- //重新实现复制否造函数
- HasPtr(const HasPtr &orig):
- ptr(orig.ptr),val(orig.val){++ptr->use;}
- HasPtr&operator=(const HasPtr& rhs);
- //获取成员变量的接口
- int *get_ptr()const { return ptr->ip;}
- int get_int const {return val;}
- //设置成员变量的接口
- void set_per(int *p){ptr->ip=p;}
- void set_int(int i){val=i;}
- int get_ptr_val()const {return *ptr->ip;}
- int set_ptr_val(int val)const {*prt->ip=val;}//指针的值没变,所以可以为const
- private:
- U_Ptr *ptr;
- int val;
- }
- //实现赋值操作符重载
- HasPtr& HasPtr::operator=(const HasPtr &rhs)
- {
- ++rhs.prt->use++;//右操作数智能指针的引用计数加1
- if(--ptr->use==0)//左操作数智能指针的引用计数减1
- delete ptr;
- ptr=rhs.ptr;
- val=rhs.val;
- return *this;
- }
0 0
- C ++中的智能指针
- C/C++: stl 和 boost 中的智能指针
- Boost中的智能指针
- Nebula中的智能指针
- Qt中的智能指针
- Boost 中的智能指针
- WebKit中的智能指针
- WebKit中的智能指针
- C++中的智能指针
- C++中的智能指针
- C++中的智能指针
- android中的智能指针
- OSG中的智能指针
- OSG中的智能指针
- c++中的智能指针
- C++ 中的智能指针
- C++中的智能指针
- C++中的智能指针
- 2016华为机试题之 找第一个“1”
- 什么是套接字(Socket)?套接字(Socket)是什么意思?(转载)
- 导出Excel工具类
- cocos2dx 解决中文乱码
- JSP 语法
- C++中的智能指针
- ng-init
- 013.php流程控制语句
- 高通开发名词整理
- Linux jar包 后台运行
- word中如何在方框中打钩
- 陈一舟:每个人风口来的时间不一样
- 5-CSS-浮动清除-继承-优先级-定位-引入CSS-盒子模型
- C语言str函数系列