目录
-
5.2 运算符重载
-
5.2.6 赋值运算符“=”的重载
1、指针悬挂问题
(1)创建对象p1和p2时,分别调用构造函数,通过运算符new分别从内存中动态分配一块空间,字符指针ptr指向内存空间
(2)执行p2=p1,调用默认的赋值运算符重载函数,使两个对象p1和p2的指针ptr都指向同一内存空间
(3)当调用虚构函数时,先撤销对象p2,释放p2所指向的内存空间,因为p1和p2指向同一内存空间,当撤销对象p1时,所指向的内存空间无法访问了,运行错误。(同一内存空间释放两次)
【指针悬挂问题说明】
执行p1=p2之前,成员指针变量ptr分别指向对应的内存空间
执行p1=p2
撤销对象p2
【指针悬挂问题示例】
#include<iostream>
#include<string.h>
using namespace std;
class STRING{
public:
STRING(char *s){
cout<<"Constructor Called."<<endl;
ptr=new char[strlen(s)+1];
strcpy(ptr,s);
}
~STRING(){
cout<<"Destructor Call.---"<<ptr<<endl;
delete ptr;
}
private:
char *ptr;
};
int main()
{
STRING p1("China");
STRING p2("America");
p2=p1;
return 0;
}
【指针悬挂示例运行结果】
2、用深层复制解决指针悬挂问题
(1)创建对象p1和p2时,分别调用构造函数,通过运算符new分别从内存中动态分配一块空间,字符指针ptr指向内存空间
(2)执行p2=p1,调用自定义的赋值运算符重载函数,释放p2指针ptr所指的旧内存空间,分配新的内存空间个p2,再把对象p1的数据成员赋给p2对应的数据成员
(3)当调用虚构函数时,先撤销对象p2,释放p2所指向的内存空间,再撤销对象p1,释放p1所指向的内存空间
【深层复制说明】
执行p1=p2之前
执行p1=p2
撤销对象p2
【深层复制】
#include<iostream>
#include<string.h>
using namespace std;
class STRING{
public:
STRING(char *s){
cout<<"Constructor Called."<<endl;
ptr=new char[strlen(s)+1];
strcpy(ptr,s);
}
~STRING(){
cout<<"Destructor Called.---"<<ptr<<endl;
delete ptr;
}
STRING &operator=(const STRING &); //声明赋值运算符重载函数
private:
char *ptr;
};
STRING &STRING::operator=(const STRING &s){ //定义赋值运算符重载函数
if(this==&s) return *this; //防止s=s的赋值
delete ptr; //释放掉原区域
ptr=new char[strlen(s.ptr)+1]; //分配新区域
strcpy(ptr,s.ptr); //字符串复制
return *this;
}
int main()
{
STRING p1("China");
STRING p2("America");
p2=p1;
return 0;
}
【深层复制运行结果】
-
5.2.7 下标运算符 “[ ]” 的重载
【示例】
#include<iostream>
using namespace std;
class Vector4{
public:
Vector4(int a1,int a2,int a3,int a4){
v[0]=a1;
v[1]=a2;
v[2]=a3;
v[3]=a4;
}
int & operator[](int bi);
private:
int v[4];
};
int &Vector4::operator[](int bi){
if(bi<0||bi>=4){
cout<<"Bad subscript!\n";
exit(1);
}
return v[bi];
}
int main()
{
Vector4 ve(1,2,3,4);
cout<<endl<<"ve[2] = "<<ve[2]; //ve.operator[](2);
return 0;
}
【示例运算结果】