C++管理指针成员
2012-08-24 16:29 javaspring 阅读(230) 评论(0) 编辑 收藏 举报1、C++中一般采用下面三种方法之一管理指针成员:
(1)指针成员采取常规行为。这样的类具有指针的所有缺陷:具有指针成员且使用默认复制构造函数和赋值操作符,无法避免悬垂指针(两个对象的指针成员指向同一内存,删除了其中一个指针指向的内存时,另一个指针将不再指向有效的内存空间)。
(2)类可以实现所谓的"智能指针"行为。引入计数类,智能指针类将一个计数器与类的对象相关联。使用计数跟踪该类有多少个对象共享同一指针。当计数为0时,删除对象。
(3)类采取值行为。采用重载的复制构造函数、赋值操作符和析构函数。
2、指针成员采取常规行为示例:两个指针指向同一块内存,会引起不可预料的后果
#include "stdafx.h" #include <string.h> #include <iostream.h> class HasPtr { public: HasPtr(int *p,int i):ptr(p),val(i){} int *get_ptr()const{return ptr;} int get_val()const{return val;} void set_ptr(int *p){ptr=p;} void set_val(int i){val=i;} int get_ptr_val()const{return *ptr;} void set_ptr_val(int val)const{*ptr=val;} private: int *ptr; int val; }; int main(int argc, char* argv[]) { int *p=new int(10); cout<<p<<endl; HasPtr ptr(p,10); cout<<ptr.get_ptr()<<endl; delete p; cout<<ptr.get_ptr_val()<<endl; //p和ptr中的指针指向同一对象。删除该对象后,ptr中的指针不再指向有效的对象。 return 0; }
3、"智能指针"行为示例:注意构造函数
#include "stdafx.h" #include <string.h> #include <iostream.h> class HasPtr; //计数类U_Ptr所有成员均为private,将HasPtr设置为计数类的友元类,使其可以访问U_Ptr的成员 class U_Ptr { friend class HasPtr; int *ip; size_t use; U_Ptr(int *p):ip(p),use(1){} ~U_Ptr() { delete ip; } }; class HasPtr { public: HasPtr(int *p,int i):ptr(new U_Ptr(new int(*p))),val(i){} //构造函数,创建新的U_Ptr对象 HasPtr(const HasPtr &orig):ptr(orig.ptr),val(orig.val){++ptr->use;} //复制构造函数,计数加1 HasPtr& operator=(const HasPtr &rhs) //赋值操作符,左操作数计数减1,右操作数计数加1,如果左操作数减至0,则删除左操作数指向的对象 { if (this!=&rhs) { ++rhs.ptr->use; if(--ptr->use==0) delete ptr; ptr=rhs.ptr; val=rhs.val; } return *this; } ~HasPtr() //析构函数,计数减1,如果计数减至0,就删除对象 { if (--ptr->use==0) { delete ptr; } } int *get_ptr()const{return ptr->ip;} int get_val()const{return val;} void set_ptr(int *p){ptr->ip=p;} void set_val(int i){val=i;} int get_ptr_val()const{return *ptr->ip;} void set_ptr_val(int val){*ptr->ip=val;} private: U_Ptr *ptr; int val; }; int main(int argc, char* argv[]) { int *p=new int(10); cout<<p<<endl; HasPtr ptr(p,10); cout<<ptr.get_ptr()<<endl; //两指针指向同一块内存 cout<<ptr.get_ptr_val()<<endl; delete p; return 0; }
4、定义值型类:三法则(赋值操作符、复制构造函数、析构函数)
#include <string.h> #include <iostream.h> class HasPtr { public: HasPtr(int *p,int i):ptr(new int(*p)),val(i){} //构造函数 HasPtr(const HasPtr &orig):ptr(new int(*orig.ptr)),val(orig.val){} //复制构造函数 HasPtr& operator=(const HasPtr &rhs) //赋值操作符 { if (this!=&rhs) { ptr=new int(*rhs.ptr); val=rhs.val; } return *this; } ~HasPtr(){delete ptr;} //析构函数 int *get_ptr()const{return ptr;} int get_val()const{return val;} void set_ptr(int *p){ptr=p;} void set_val(int i){val=i;} int get_ptr_val()const{return *ptr;} void set_ptr_val(int val)const{*ptr=val;} private: int *ptr; int val; }; int main(int argc, char* argv[]) { int *p=new int(10); cout<<p<<endl; HasPtr ptr(p,10); cout<<ptr.get_ptr()<<endl; //p与ptr的指针不是指在同一块内存,但是所指向的对象内容是一样的 delete p; cout<<ptr.get_ptr_val()<<endl; return 0; }