C++管理指针成员

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

 

转载于:https://www.cnblogs.com/javaspring/archive/2012/08/24/2656059.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值