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;
- }