类中默认的赋值运算符重载带来的“指针悬挂”问题

赋值运算符重载的指针悬挂问题
  • 对任一类X,如果用户没有自定义的赋值运算符函数,那么编译系统将自动的为其生成一个默认的赋值运算符函数,默认赋值运算符函数重载形式如下:
    X&X::operator =(const X & source) { 成员间赋值 }

  • 若obj1和obj2是类X的两个对象,obj2已经被创建,则编译系统执行obj1=obj2时,就会调用默认的赋值运算符函数,它将对象obj2的数据成员逐一复制到对象obj1的数据成员中。

  • 通常,默认的赋值运算符是可以正常工作的,但是在某些特殊情况下,如类中有指针类型时,使用默认赋值运算符会产生错误,这个错误被称为“指针悬挂”。

  • 下面是一个使用默认赋值运算符函数造成的指针悬挂实例。

  • 主函数里,我们用大括号将一部分代码的生存期改变了,而不是使用的注释代码。这样做的原因是为了说明指针悬挂问题。编译系统调用默认赋值函数执行s2=s1后,s1和s2都指向了同一块内存空间,这时输出s2的内容为Lin。但当s2生存期结束时,调用了析构函数释放了指针指向的空间后,造成s1指针悬挂,内存访问错误,输出乱码。(有点类似于默认复制构造函数中当有指针类型数据,复制析构后带来的内存崩溃问题。)

  • 解决方法当然是自定义赋值运算符函数。

#include <iostream>

using namespace std;

//指针悬挂实例
class Student{
	private:
		char* name;
	public:
		Student(char* ptr)
		{
			name=new char[strlen(ptr)+1];
			strcpy(name,ptr);
		} 
		void print()
		{
			cout<<name<<endl;
		}
		~Student()
		{
			delete [] name;
		}
};

int main()
{
	Student s1("Lin");
	{
		Student s2("");
		s2=s1;
		cout<<"s2:";
		s2.print();
	}
	s1.print();
//	Student s2("");
//	s2=s1;
//	s2.print();
//	s1.print();
	return 0;
}

运行结果:
/

自定义赋值运算符函数解决指针悬挂问题
  • 默认赋值运算符函数重载形式如下:
    X&X::operator =(const X & source) { 成员间赋值 }
  • 那么在上例中,加上自定义的赋值运算符函数即可:
    Student& operator =(const Student & s)
    {
    name=new char[strlen(s.name)+1];
    strcpy(name,s.name);
    }
  • 显然,我们不仅复制了内容,还new了空间,这样两个指针对应了两个空间,不会再出现指针悬挂。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值