由C++的 复制构造器和
=
运算符重载入手,总结默认的
成员赋值(浅拷贝)与深拷贝,最后探究程序中常见的对象赋值和拷贝。如有指正或补充,请不吝指出。
还是以一个例子辅以说明,这里使用一个自定义带编号字符串类MyString
,每一个字符串对象都由其编号和字符串内容唯一确定。
1、赋值运算符与复制构造器
定义MyString
类后,看如下语句:
MyString str1("C++"); //使用构造器
//先声明,再赋值
MyString str2;
str2=str1;
//声明并初始化
MyString str3=str1;
上面str2
和str3
的两种赋值方式是否有区别?首先,从结果来看,它们是等效的,都是创建了一个字符串,并把str赋给它。但二者实现过程却具有本质的不同。前者是先使用无参构造器创建对象,再通过赋值运算把str1赋给该对象;后者是直接从复制构造器创建一个对象。因此,C++中的"初始化"特指声明的同时赋值。
1.1、赋值运算符
编译器会在类没有重载=
运算符的时候提供默认的赋值运算操作,默认赋值只进行简单的成员赋值。如,在MyString
中,类这样:
/*MyString对象具有属性成员: id,len,str(char*)*/
MyString& MyString::operator=(const MyString& s){
id=s.id;
len=s.len;
str=s.str; //直接把指针赋值
}
所以,即使没有重载=
,类对象也能进行赋值,但这种赋值不一定安全。
1.2、复制构造器
复制构造器(copy constructor)是编译器默认为类添加的构造器。是的,编译器除了在没有构造器的时候提供默认无参构造器,还会在你没有提供复制构