# **對象的復制**
## **特殊函數**
* 拷貝賦值操作
* 拷貝構造函數
# **拷貝構造函數**
## **定義方式**
* 類名(類名& 對象)
* 類名(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 類模板
- 第四章 運算符重載
- 數據類型轉換
- 運算符重載
- 重載流插入運算符和流提取運算符
- 第五章 繼承與派生
- 繼承與派生
- 第六章 多態性與虛函數
- 多態性
- 虛函數
- 純虛函數與抽象類