转移构造函数 & 转移赋值操作符重载函数
转移构造函数 & 转移赋值操作符重载函数
拷贝构造 在创建一个对象时用另一个同类型的 对象对其初始化时,将会调用拷贝构 造函数
拷贝构造 ◼ 在创建一个对象时用另一个同类型的 对象对其初始化时,将会调用拷贝构 造函数
class A char *p; public: A(char *str) p new char[strlen(str)+1]; strcpy(p,str); } A(const A&x)/拷贝构造函数 {p=new char[strlen(x.p)+l];/申请空间 strcpy(p,x.p);/内容复制 ~A() {delete[]p;/归还空间 P=NULL; void g(){.….} bi
class A { char *p; public: A(char *str) { p = new char[strlen(str)+1]; strcpy(p,str); } A(const A& x) //拷贝构造函数 { p = new char[strlen(x.p)+1]; //申请空间 strcpy(p,x.p); //内容复制 } ~A() { delete[]p; //归还空间 p = NULL; } void g() { ...... } };
void f1(A x){......} Af2() return..;//调用拷贝构造函数创建临时对象(返回值) Aa("abcd"); Ab(a);/调用拷贝构造函数创建对象b f1(a);/调用拷贝构造函创建对象x f2().g();/调用返回的临时对象的成员函数g
void f1(A x) { ...... } A f2() { ...... return ...; //调用拷贝构造函数创建临时对象(返回值) } ...... A a("abcd"); A b(a); //调用拷贝构造函数创建对象b f1(a); //调用拷贝构造函创建对象x f2().g(); //调用返回的临时对象的成员函数g
拷贝构造的问题 当用一个临时或即将消亡的对象去初始化 另一个同类的对象时,目前的拷贝构造函 数的实现效率有时是不高的
拷贝构造的问题 ◼ 当用一个临时或即将消亡的对象去初始化 另一个同类的对象时,目前的拷贝构造函 数的实现效率有时是不高的
A f() {At("1234");/创建局部对象t(调用构造函数) return t;/创建返回值对象,用即将消亡的对象t对其 //初始化(调用拷贝构造函数),然后, /对象t消亡(调用析构函数 int main() f(O.g(O;/使用函数f的返回值对象, /然后,该返回值对象消亡(调用析构函数〉 问题:为什么不把对象t申请的空间直接带到返回值对象中呢?
A f() { A t("1234"); //创建局部对象t(调用构造函数) ...... return t; //创建返回值对象,用即将消亡的对象t对其 //初始化(调用拷贝构造函数),然后, //对象t消亡(调用析构函数) } int main() { ...... f().g(); //使用函数f的返回值对象, //然后,该返回值对象消亡(调用析构函数) ...... } 问题:为什么不把对象t申请的空间直接带到返回值对象中呢?
转移构造函数 ▣为了解决上面的问题,C++新国际标准 (C++11)为C++提供了一种新的构造函数 一一转移构造函数(move constructor) ·A(A&&x);/参数类型为右值引用类型:&& 当用一个临时对象或即将消亡的对象去初始化 另一个对象时 如果对象类中有转移构造函数,则会去调用转移构 造函数来对对象初始化。(注意:系统不会提供隐 式转移构造函数!) 否则去调用拷贝构造函数进行对象初始化
转移构造函数 ◼ 为了解决上面的问题,C++新国际标准 (C++11)为C++提供了一种新的构造函数 ――转移构造函数(move constructor): • A(A&& x); //参数类型为右值引用类型:&& ◼ 当用一个临时对象或即将消亡的对象去初始化 另一个对象时, • 如果对象类中有转移构造函数,则会去调用转移构 造函数来对对象初始化。(注意:系统不会提供隐 式转移构造函数!) • 否则去调用拷贝构造函数进行对象初始化
在转移构造函数中实现资源的转移: A(A&&x)/参数类型为右值引用类型&& {p=X.p;/把参数对象x的p所指向的空间作为 /新对象的p所指向的空间(资源转移》 ×.p=NU儿L;/使得参数对象x的p不再拥有 /原来所指向的空间 有了上述转移构造函数之后,前面例子中的 “return t;”就会去调用它来实现资源的转 移!
◼ 在转移构造函数中实现资源的转移: A(A&& x) //参数类型为右值引用类型&& { p = x.p; //把参数对象x的p所指向的空间作为 //新对象的p所指向的空间(资源转移) x.p = NULL; //使得参数对象x的p不再拥有 //原来所指向的空间。 } ◼ 有了上述转移构造函数之后,前面例子中的 “return t;”就会去调用它来实现资源的转 移!
赋值操作符重载 ·把一个对象赋值给另一个对象 时,将会去调用对象类的赋值 操作符重载函数
赋值操作符重载 ◼把一个对象赋值给另一个对象 时,将会去调用对象类的赋值 操作符重载函数
class A char *p; public: A(char *str) p new char[strlen(str)+1];strcpy(p,str); } ~A()delete[]p;p NULL; A&operator:=(const A&X)/赋值操作符重载函数 if (&x =this)return *this; delete[]p;/归还老空间 p=new char[strlen(x.p)+1]:/申请新空间 strcpy(p,x.p)i/内容复制 return *this;
class A { char *p; public: A(char *str) { p = new char[strlen(str)+1]; strcpy(p,str); } ~A() { delete[]p; p = NULL; } A& operator=(const A& x) //赋值操作符重载函数 { if (&x == this) return *this; delete []p; //归还老空间 p = new char[strlen(x.p)+1]; //申请新空间 strcpy(p,x.p); //内容复制 return *this; } ...... };