合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
# **对象的复制** ## **特殊函数** * 拷贝赋值操作 * 拷贝构造函数 # **拷贝构造函数** ## **定义方式** * 类名(类名& 对象) * 类名(const 类名& 对象) //防止在后续操作中改变原对象的值 ## **特点** * 有一个及以上的形参 * 第一个形参类型为 类名& * 不能指定返回类型 * 若用户没有定义,则编译器会自己生成一个 X::X(const X&)的**缺省的拷贝构造函数,**作用为一一照赋 ## **调用时机** * 用一个已经存在的对象去初始化另一个正在被创建的对象时; 用new操作符带对象参数创建对象时; * 对象作函数参数传递时; * 对象作函数的返回值时. ~~~ //1 Student st("tony"); student st1 = st; ​ Student s1("Jenny"); Student *p=new Student(s1); ​ //2 Student st; fn(st); ~~~ ## **例子** ~~~ #include <iostream> using namespace std; ​ class Student { private:   int id; ​ public:   Student(int a):id(a){               cout<<"调用普通构造函数--id:"<<id<<endl;   } ​   ~Student(){       cout<<"调用析构函数"<<endl;   } ​   Student(Student& s){       cout<<"调用拷贝函数--拷贝id:"<<s.id<<endl;           } }; ​ int main() {   Student stu(123);   Student sstu1(stu); ​   return 0; } ~~~ ~~~ //结果 id:123 拷贝id:123 析构 析构 ~~~ # **默认拷贝构造函数** ## **特点** 如果数据成员的值是在动态分配空间,拷贝时只是将该数据成员的地址,与拷贝的对象之间建立联系,并不会重新分配空间,在调用析构函数时,可能会出错。 ## **深拷贝** 复制对象的时候重新创建空间。 * **优点** 简单,每个对象拥有独立的空间。 * **缺点** 内存开销较大,速度慢。(时间复杂度和空间复杂度高,为线性级) * **适用** 存储较少数据的容器。 ## **浅拷贝法** 设置一个数据成员 `power` ,对象复制的时候,将运算符右边的对象的 `power` 设置为 `false`。析构的时候,若 `power` 为 `false` 则不删除动态空间。 * **优点** 内存开销小。(时间复杂度和空间复杂度低,为常数级) * **缺点** 不同对象之间占用同一片内存区域,修改那一块区域的值,所有对象获得的数据都会改变。 * **适用** 存储较多数据的容器。 # 对象的赋值 ## 拷贝赋值操作 缺省的拷贝赋值操作声明 ~~~ X& operator = (const X& p); // 加上& 是为了和拷贝构造函数区分 ~~~ ## 特点 * 拷贝构造函数时在声明时赋值 * 拷贝赋值操作是在声明之后,在赋值 * 默认拷贝赋值操作是浅拷贝 * 声明类时,如果没有声明拷贝赋值操作,编译器会自动生成默认拷贝赋值操作 ## 例子 ~~~ #include <iostream> using namespace std; ​ class Box { public:   Box(int=10,int=10,int=10);       //声明有默认参数的构造函数       int volume( );   private:   int height;       int width;       int length; }; ​ Box∷Box(int h,int w,int len) { height=h;   width=w;   length=len; } ​ int Box∷volume( ) { return(height*width*length);     //返回体积 } ​ int main( ) { Box box1(15,30,25),box2;                       //定义两个对象box1和box2   cout<<″The volume of box1 is ″   <<box1.volume( )<<endl;   box2=box1;           //将box1的值赋给box2   cout<<″The volume of box2 is ″   <<box2.volume( )<<endl;   return 0; } ~~~ ~~~ 结果: The volume of box1 is 11250 The volume of box2 is 11250 ~~~