C++_指针悬挂和赋值操作符的重载
2013-10-26 21:24
295 查看
指针悬挂:
问题:使用new申请的内存内存空间无法访问,也无法释放。
原因:直接对指向new申请的存储空间的指针变量进行赋值修改
后果:失去了原来的地址,原来的空间无法访问也无法释放,造成内存泄漏
还可能造成同一个内存释放两次
容易引起指针悬挂的方式:对象的初始化和对象间赋值
容易引起指针悬挂的条件:类中含有指针类型的成员时,使用默认的拷贝构造函数和赋值函数都会出现两个指针变量互相赋值,产生指针悬挂的问题。
解决方法:需要重新定义拷贝构造函数和超载赋值运算符
赋值操作符:
作用:两个已经存在的对象间相互赋值,产生两个完全相同的内存拷贝
举例:string a("hello");//调用构造函数
string b("would");//调用构造函数
string c=a;//调用拷贝构造函数--风格差,应使用string c(a)
c=b; //调用拷贝赋值函数
重载赋值运算符:
语法:
[html]
view plaincopyprint?
X& X::operator=(const X & fm)
{
函数体
}
注意:
1、第一个引用的作用(为什么使用返回函数引用):
原因:为了实现对象间的连续赋值。
使用返回函数引用的好处:结果得到的是一个变量,它既可以当左值,也可当右值,且采用赋值时没有引入临时变量,直接从原结果拷贝。
2、第二个引用的作用:防止调用拷贝构造函数,因为拷贝构造函数也可能引起指针悬挂
3、const的作用:当参数使用引用时,可能会改变传入的参数,为了避免这样,就使用const
具体代码:
[cpp]
view plaincopyprint?
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;
}
拷贝构造函数和重载赋值运算符的代码对比:
[cpp]
view plaincopyprint?
Point::Point(const Point& p)//拷贝构造函数
Point& Point::operator=(const Point&p)//重载赋值运算符
注意:
1、参数都是一样的,都有const和引用,但是带他们的原因不同,具体见上面。
2、拷贝构造函数无返回值,而重载赋值运算符使用 返回函数引用。
问题:使用new申请的内存内存空间无法访问,也无法释放。
原因:直接对指向new申请的存储空间的指针变量进行赋值修改
后果:失去了原来的地址,原来的空间无法访问也无法释放,造成内存泄漏
还可能造成同一个内存释放两次
容易引起指针悬挂的方式:对象的初始化和对象间赋值
容易引起指针悬挂的条件:类中含有指针类型的成员时,使用默认的拷贝构造函数和赋值函数都会出现两个指针变量互相赋值,产生指针悬挂的问题。
解决方法:需要重新定义拷贝构造函数和超载赋值运算符
赋值操作符:
作用:两个已经存在的对象间相互赋值,产生两个完全相同的内存拷贝
举例:string a("hello");//调用构造函数
string b("would");//调用构造函数
string c=a;//调用拷贝构造函数--风格差,应使用string c(a)
c=b; //调用拷贝赋值函数
重载赋值运算符:
语法:
[html]
view plaincopyprint?
X& X::operator=(const X & fm)
{
函数体
}
X& X::operator=(const X & fm) { 函数体 }
注意:
1、第一个引用的作用(为什么使用返回函数引用):
原因:为了实现对象间的连续赋值。
使用返回函数引用的好处:结果得到的是一个变量,它既可以当左值,也可当右值,且采用赋值时没有引入临时变量,直接从原结果拷贝。
2、第二个引用的作用:防止调用拷贝构造函数,因为拷贝构造函数也可能引起指针悬挂
3、const的作用:当参数使用引用时,可能会改变传入的参数,为了避免这样,就使用const
具体代码:
[cpp]
view plaincopyprint?
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;
}
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; }
拷贝构造函数和重载赋值运算符的代码对比:
[cpp]
view plaincopyprint?
Point::Point(const Point& p)//拷贝构造函数
Point& Point::operator=(const Point&p)//重载赋值运算符
Point::Point(const Point& p)//拷贝构造函数 Point& Point::operator=(const Point&p)//重载赋值运算符
注意:
1、参数都是一样的,都有const和引用,但是带他们的原因不同,具体见上面。
2、拷贝构造函数无返回值,而重载赋值运算符使用 返回函数引用。
相关文章推荐
- C++_指针悬挂和赋值操作符的重载
- C++ 指针悬挂和赋值操作符的重载,拷贝构造函数实现
- C++ 指针悬挂和赋值操作符的重载,拷贝构造函数实现
- 批注:C++中复制构造函数与重载赋值操作符总结:默认浅拷贝,带指针的需要深拷贝
- C++学习笔记-类5-浅拷贝和深拷贝以及赋值操作符的重载
- C++ 中指针操作符(*)重载备忘
- c++ 重载赋值操作符
- C++ 拷贝构造函数和重载赋值操作符相互调用分析 [转]
- C++ 之 重载赋值操作符
- C++中cout/cin对于空指针、字符指针的处理,及输入>>、 输出<<操作符的重载
- 详解C++-(=)赋值操作符、智能指针编写
- c++中赋值操作符的重载
- C++ 操作符赋值重载
- 我的学习笔记——c++拷贝构造函数,重载赋值操作符
- C++——如何重载*(指针)操作符
- C++中复制构造函数与重载赋值操作符
- C++ 重载赋值操作符
- 【C++深度剖析教程12】数组操作符的重载
- c++ 赋值操作符的返回值
- C++箭头操作符重载