///*重载赋值运算符
//重载的格式 a &a::operator(const a&from){}
//返回类型的引用是为了与c++原有赋值号的语义相匹配
//用const是为了保证函数体内部修改实际参数
//相关的说明:重载赋值运算符必须是成员函数
//若是程序员没有为类重载赋值运算符重载,将自动生成一个缺省的赋值运算符
//关于指针悬挂的说明:使用缺省的赋值运算符时,对于简单的类(例如complex),缺省赋值函数
//可以完成相关的工作。但是数据成员包含指针时,就会出现问题
//举个例子说明
//struct string
//{char *p;int size;
//string(int sz){p=new char[size=sz];}
//~string(){delete p;}
//}
//void fun()
//{string s1(10);string s2(10);s1=s2;
//}
//将s2的指针p和整型量size的值拷贝到s1。从而导致原来s1所指向的那块内存区域被封锁住,
//不能使用。而对s2所指向的区域,调用两次的析构函数,将同一块内存释放两次。
//所以需要重载“=”运算符
//*/
//#include <iostream>
//#include <cstring>//标准函数strcpy()原型在其中
using namespace std;
//struct string
//{char *p;int size;
//string(int sz){p=new char[size=sz];}
//~string(){delete p;}//是否可以输入表达式p[],或者其他的形式呢??
//void operator=(string&a);
//};
//void string::operator=(string&a)
//{
// if(this==&a)return;//防止s1=s1
// delete p;
// p=new char[size=a.size];//重新分配s1的空间
// strcpy(p,a.p);//对于strcpy这个函数,只需要加入iostream头文件即可
//}
//void main()
//{
// string s1(10);
// string s2(10);
// s1=s2;
//}
/*赋值运算符的重载,补充说明
赋值运算符,深拷贝和浅拷贝的问题*/
#include<iostream>
#include<cstring>
using namespace std;
class person
{
char *pname;
public:
/*类型转换构造函数,把形参字符串指针pN所指的(实参)字符串常量转换为person类的对象,
并将该字符串常量保存在该对象中*/
person(char *pN)
{static int j=0;//记录调用本构造函数的次数
cout<<"第"<<++j<<"次调用类型转换的构造函数!\n";
//输出显示调用的构造函数信息
pname=new char[strlen(pN)+1];
/*在堆中开辟存放pN所指的(实参)字符串常量的空间*/
if(pname) strcpy(pname,pN);
/*if(pname)也是可以写成if(pname!=Null)*/
}
person(person&p);//复制构造函数的声明
person & operator=(person &p);//此形参应该是可以改动的
~person()
{
static int k=0;//记录调用的析构函数的次数
cout<<"第"<<++k<<"次调用析构函数!\n";
//pname[0]='\0';//将要撤销对象的私有数据成员pname所指的字符串设置成空窜
delete pname;
}
void display()
{
cout<<pname<<endl;
}
};
person::person(person&p)//复制构造函数
{
cout<<"调用复制构造函数!\n";
pname=new char[strlen(p.pname)+1];//
/*将p的数据成员pname所指的字符串常量*/
if(pname)strcpy(pname,p.pname);
}
person& person::operator=(person&p)//使用的是引用的形式
//person person::operator=(person&s)
/*若是使用这个为函数,则结果在调用一次赋值运算符函数之后又调用了一次的复制构造函数*/
{
cout<<"调用赋值运算符函数!\n";
if(pname)
{delete pname;pname='\0';}//删除目标对象原有的内存空间
pname=new char[strlen(p.pname)+1];//给目标对象重新分配内存空间
if(pname)
strcpy(pname,p.pname);
return *this;//返回调用本成员函数的对象
}
void main()
{
person p1("i love chi");
person p2=p1;//调用复制构造函数
p1.display();
p2.display();
person p3("new object");
p3.display();
p3=p1;/*当不适用引用的时候。在实际编程过程中发现,这条语句中,
包含调用一次赋值运算符函数和一次的复制构造函数,再调用一次析构函数
使用引用的时候,就不需要调用复制构造函数了*/
p3.display();
}
//重载的格式 a &a::operator(const a&from){}
//返回类型的引用是为了与c++原有赋值号的语义相匹配
//用const是为了保证函数体内部修改实际参数
//相关的说明:重载赋值运算符必须是成员函数
//若是程序员没有为类重载赋值运算符重载,将自动生成一个缺省的赋值运算符
//关于指针悬挂的说明:使用缺省的赋值运算符时,对于简单的类(例如complex),缺省赋值函数
//可以完成相关的工作。但是数据成员包含指针时,就会出现问题
//举个例子说明
//struct string
//{char *p;int size;
//string(int sz){p=new char[size=sz];}
//~string(){delete p;}
//}
//void fun()
//{string s1(10);string s2(10);s1=s2;
//}
//将s2的指针p和整型量size的值拷贝到s1。从而导致原来s1所指向的那块内存区域被封锁住,
//不能使用。而对s2所指向的区域,调用两次的析构函数,将同一块内存释放两次。
//所以需要重载“=”运算符
//*/
//#include <iostream>
//#include <cstring>//标准函数strcpy()原型在其中
using namespace std;
//struct string
//{char *p;int size;
//string(int sz){p=new char[size=sz];}
//~string(){delete p;}//是否可以输入表达式p[],或者其他的形式呢??
//void operator=(string&a);
//};
//void string::operator=(string&a)
//{
// if(this==&a)return;//防止s1=s1
// delete p;
// p=new char[size=a.size];//重新分配s1的空间
// strcpy(p,a.p);//对于strcpy这个函数,只需要加入iostream头文件即可
//}
//void main()
//{
// string s1(10);
// string s2(10);
// s1=s2;
//}
/*赋值运算符的重载,补充说明
赋值运算符,深拷贝和浅拷贝的问题*/
#include<iostream>
#include<cstring>
using namespace std;
class person
{
char *pname;
public:
/*类型转换构造函数,把形参字符串指针pN所指的(实参)字符串常量转换为person类的对象,
并将该字符串常量保存在该对象中*/
person(char *pN)
{static int j=0;//记录调用本构造函数的次数
cout<<"第"<<++j<<"次调用类型转换的构造函数!\n";
//输出显示调用的构造函数信息
pname=new char[strlen(pN)+1];
/*在堆中开辟存放pN所指的(实参)字符串常量的空间*/
if(pname) strcpy(pname,pN);
/*if(pname)也是可以写成if(pname!=Null)*/
}
person(person&p);//复制构造函数的声明
person & operator=(person &p);//此形参应该是可以改动的
~person()
{
static int k=0;//记录调用的析构函数的次数
cout<<"第"<<++k<<"次调用析构函数!\n";
//pname[0]='\0';//将要撤销对象的私有数据成员pname所指的字符串设置成空窜
delete pname;
}
void display()
{
cout<<pname<<endl;
}
};
person::person(person&p)//复制构造函数
{
cout<<"调用复制构造函数!\n";
pname=new char[strlen(p.pname)+1];//
/*将p的数据成员pname所指的字符串常量*/
if(pname)strcpy(pname,p.pname);
}
person& person::operator=(person&p)//使用的是引用的形式
//person person::operator=(person&s)
/*若是使用这个为函数,则结果在调用一次赋值运算符函数之后又调用了一次的复制构造函数*/
{
cout<<"调用赋值运算符函数!\n";
if(pname)
{delete pname;pname='\0';}//删除目标对象原有的内存空间
pname=new char[strlen(p.pname)+1];//给目标对象重新分配内存空间
if(pname)
strcpy(pname,p.pname);
return *this;//返回调用本成员函数的对象
}
void main()
{
person p1("i love chi");
person p2=p1;//调用复制构造函数
p1.display();
p2.display();
person p3("new object");
p3.display();
p3=p1;/*当不适用引用的时候。在实际编程过程中发现,这条语句中,
包含调用一次赋值运算符函数和一次的复制构造函数,再调用一次析构函数
使用引用的时候,就不需要调用复制构造函数了*/
p3.display();
}