C++_指针悬挂和赋值操作符的重载

指针悬挂:

问题:使用new申请的内存内存空间无法访问,也无法释放。

原因:直接指向new申请的存储空间的指针变量进行赋值修改

后果:失去了原来的地址,原来的空间无法访问也无法释放,造成内存泄漏

            还可能造成同一个内存释放两次

容易引起指针悬挂的方式:对象的初始化和对象间赋值

容易引起指针悬挂的条件:类中含有指针类型的成员时,使用默认的拷贝构造函数和赋值函数都会出现两个指针变量互相赋值,产生指针悬挂的问题。

解决方法:需要重新定义拷贝构造函数和超载赋值运算符

赋值操作符:    

 作用:两个已经存在的对象间相互赋值,产生两个完全相同的内存拷贝

 举例:string a("hello");//调用构造函数

             string b("would");//调用构造函数

             string c=a;//调用拷贝构造函数--风格差,应使用string c(a)

             c=b;  //调用拷贝赋值函数

重载赋值运算符:

语法:

  1. X& X::operator=(const X & fm)  
  2. {  
  3.     函数体  
  4. }  
X& X::operator=(const X & fm)
{
	函数体
}

注意:

          1、第一个引用的作用(为什么使用返回函数引用):

                原因:为了实现对象间的连续赋值。

               使用返回函数引用的好处:结果得到的是一个变量,它既可以当左值,也可当右值,且采用赋值时没有引入临时变量,直接从原结果拷贝。

          2、第二个引用的作用:防止调用拷贝构造函数,因为拷贝构造函数也可能引起指针悬挂

          3、const的作用:当参数使用引用时,可能会改变传入的参数,为了避免这样,就使用const

具体代码:

  1. class Point  
  2. {  
  3. private:  
  4.     char * name;  
  5. public:  
  6.     Point(char * className)  
  7.     {  
  8.         name = new char[strlen(className)+1];  
  9.         strcpy(name, className);  
  10.     }  
  11.     Point(const Point& p)//深拷贝   
  12.     {  
  13.         name = new char[strlen(p.name)+1];  
  14.         strcpy(name,p.name);  
  15.     }  
  16.     ~Point()  
  17.     {  
  18.         cout<<name<<endl;  
  19.         delete []name;  
  20.     }  
  21.     Point& operator=(const Point&p);  
  22. };  
  23. 系统自带的等号运算符:  
  24. Point& Point::operator=(const Point&p)  
  25. {  
  26.     name=p.name;//造成指针悬挂   
  27. }  
  28. 重载后的等号运算符:  
  29. Point& Point::operator=(const Point&p)  
  30. {        
  31.     delete[]name;//释放原来的         
  32.     name=new char[strlen(p.name)+1];        
  33.     strcpy(name,p.name);          
  34.     return *this;      
  35. }  
class Point
{
private:
	char * name;
public:
	Point(char * className)
	{
		name = new char[strlen(className)+1];
		strcpy(name, className);
	}
	Point(const Point& p)//深拷贝
	{
		name = new char[strlen(p.name)+1];
		strcpy(name,p.name);
	}
	~Point()
	{
		cout<<name<<endl;
		delete []name;
	}
	Point& operator=(const Point&p);
};
系统自带的等号运算符:
Point& Point::operator=(const Point&p)
{
	name=p.name;//造成指针悬挂
}
重载后的等号运算符:
Point& Point::operator=(const Point&p)
{      
	delete[]name;//释放原来的      
	name=new char[strlen(p.name)+1];      
	strcpy(name,p.name);        
	return *this;    
}

拷贝构造函数和重载赋值运算符的代码对比:

  1. Point::Point(const  Point& p)//拷贝构造函数   
  2. Point& Point::operator=(const Point&p)//重载赋值运算符  
Point::Point(const  Point& p)//拷贝构造函数
Point& Point::operator=(const Point&p)//重载赋值运算符

注意:

         1、参数都是一样的,都有const和引用,但是带他们的原因不同,具体见上面。

         2、拷贝构造函数无返回值,而重载赋值运算符使用 返回函数引用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值