# **对象的复制**
## **特殊函数**
* 拷贝赋值操作
* 拷贝构造函数
# **拷贝构造函数**
## **定义方式**
* 类名(类名& 对象)
* 类名(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
~~~
- 介绍
- 编程设计语言
- 第一章 对C++的初步认识
- 1.2 最简单的C++程序
- 1.3 C++对C的补充
- 1.3.1 return
- 1.3.2 输入输出流
- 1.3.3 putchar 和 getchar
- 1.3.4 用const定义常变量
- 1.3.5 函数原型声明
- 1.3.6 内置函数
- 1.3.7 函数重载
- 1.3.8 函数模板
- 1.3.9 有默认值的参数
- 1.3.10 作用域
- 1.3.11 const修饰指针
- 1.3.12 引用
- 1.3.13 生命期
- 1.3.14 变量
- 1.3.15 字符串变量
- 第二章 类与对象
- 2.2 类的声明和对象的定义
- 2.3 类的成员函数
- 第三章 关于类和对象的进一步讨论
- 3.1 构造函数
- 3.1.1 对象的初始化
- 3.1.2 构造函数
- 3.2 析构函数
- 3.3调用析构函数和构造函数的顺序
- 3.4 对象数组
- 3.5 对象指针
- 3.6 共享数据的保护
- 3.7 对象的建立与释放
- 3.8 对象的赋值与复制
- 3.9 静态成员
- 3.10 友元
- 3.11 类模板
- 第四章 运算符重载
- 数据类型转换
- 运算符重载
- 重载流插入运算符和流提取运算符
- 第五章 继承与派生
- 继承与派生
- 第六章 多态性与虚函数
- 多态性
- 虚函数
- 纯虚函数与抽象类