C 物件的賦值和複製

2022-03-18 00:28:06 字數 4781 閱讀 3230

3.6.1 物件賦值語句

如同基本型別賦值語句一樣,同型別的物件之間也可以進行賦值,即乙個物件的值可以賦給

另乙個物件。這裡所指的物件的賦值是指對其中的資料成員賦值,而不對成員函式賦值。

例如:a和b是同一類的兩個物件,那麼下述物件賦值語句

b=a;

就能把物件a的資料成員的值逐位複製給物件b

//

例3.24 物件賦值語句示例

#includeusing

namespace

std;

class

myclass

void

show()

private

:

inta,b;

}; int

main()

/*該程式中,語句:

o2 = o1;

等價於語句:

o2.a = o1.a;

o2.b = o1.b;

因此,執行此程式將顯示:

20 5

20 5

說明:1、在使用物件賦值語句進行物件賦值時,兩個物件的型別必須相同,如物件的型別不同,

編譯時將出錯。

2、兩個物件之間的賦值,僅僅使這些物件中資料成員相同,而兩個物件仍是分離的。例如

本例物件後,再呼叫o1.set()設定o1的值,不會影響o2的值。

3、物件賦值是通過預設賦值運算子函式實現的

4、將乙個物件的值賦給另乙個物件時,多數情況下都是成功的,但當類中存在指標時,可能

會產生錯誤。

*/

3.6.2 拷貝建構函式

拷貝建構函式是一種特殊的建構函式,其形參是本類物件的引用。拷貝建構函式的作用

是,在建立乙個新物件時,使用乙個已經存在的物件去初始化這個新物件。

例如: point p2(p1);

其作用是:在建立新物件p2時,用已經存在的物件p1去初始化物件p2,在這個過程中就要

呼叫拷貝建構函式。

拷貝建構函式具有以下特點:

(1)因為該函式也是一種建構函式,所以其函式名與類名相同,並且該函式也沒有返回值

型別。(2)該函式只有乙個引數,並且是同類物件的引用

(3)每乙個類都必須有乙個拷貝建構函式。程式設計師可以自定義拷貝建構函式,用於按照需要

初始化新物件。如果程式設計師沒有定義類的拷貝建構函式,系統就會自動生成產生乙個預設的拷貝

建構函式,用於複製出資料成員值完全相同的新物件。

1. 自定義拷貝建構函式

一般格式: 類名::類名(const 類名 &物件名)

下面是乙個使用者自定義的拷貝建構函式:

class point

point(const point &p) //拷貝建構函式

.....

private:

int x;

int y;

};

假如p1為類point的乙個物件,則下述語句可以在建立新物件p2時呼叫拷貝建構函式初始化p2;

point p2(p1);

//例3.25 自定義拷貝建構函式的使用。

#includeusing

namespace

std;

class

point

point::point(

const point &p) //

自定義的拷貝建構函式

void

print()

private

:

intx;

inty;

};int

main() /*

本例中定義物件p2時,呼叫了自定義拷貝建構函式。程式執行結果如下:

30 40

60 80

呼叫拷貝建構函式的一般形式為:

類名 物件2(物件1);

上面的這種拷貝建構函式的方法稱為「代入法」。除了用代入法呼叫拷貝建構函式外,

還可以採用"賦值法"呼叫拷貝建構函式,與基本型別的變數初始化類似.這種呼叫方的一般格式為:

類名 物件2=物件1;

當然,這種方法可以在乙個語句中進行多個物件的複製。如

point p2=p1,p3=p1;

如將例3.25主函式main改為如下形式:

int main()

2. 預設的拷貝建構函式(程式設計師沒有定義,系統會自動生成)

// 例3.26 預設的拷貝建構函式

#includeusing

namespace

std;

class

point

//point::point(const point &p)

//不用寫,系統會預設存在(需要用時直接呼叫)

//void

print()

private

:

intx;

inty;

};int

main() /*

呼叫拷貝建構函式的方法有兩種:代入法、賦值法

代入法:point p2(p1)

賦值法:point p2=p1

*/

3.呼叫拷貝建構函式的三種情況

(1)當用類的乙個物件去初始化另乙個物件時,拷貝建構函式將會被呼叫,

如例3.26主函式中的下屬語句

point p2(p1); //用代入法呼叫預設的拷貝建構函式,用物件p1初始化物件p2

point p3=p1; //用賦值法呼叫預設的拷貝建構函式,用物件p1初始化物件p3

(2)當函式的形參是類的物件,在呼叫函式進行形參和實參結合時,拷貝建構函式將會被呼叫

例如:void fun1(point p) //形參是類point的物件p

int main()

理解:在main函式內,執行語句「fun1(p1)」,便是這種情況。在呼叫這個函式時,物件p1是實參

用它來初始化被呼叫函式的形參p時,需要呼叫拷貝建構函式。這時,如果類point中有自定義

的拷貝建構函式時,就呼叫拷貝的建構函式,否則就呼叫系統自動生成的預設拷貝建構函式

(3)當函式的 返回值是類的物件,在函式呼叫完畢將返回值(物件)帶**用處時。此時將會

呼叫拷貝建構函式,將此物件賦值給乙個臨時物件並傳到該函式的呼叫處。

例如: point fun2() //函式fun2()的返回值型別是point類型別

int main()

理解:由於物件p1是函式fun2中定義的,在呼叫函式fun2結束時,p1的生命週期結束了,因此在

函式fun2結束之前,執行語句"return p1"時,將會呼叫拷貝建構函式將p1的值複製到乙個

臨時物件中,這個臨時物件是系統在主程式中臨時建立的。函式執行結束時,p1物件消失,

但是臨時物件將會通過語句"p2=fun2()"將它的值賦給物件p2,執行完這個語句後,臨時對

象變自動消失了。

//

例3.27 演示呼叫拷貝建構函式的3中情況

#include

using

namespace

std;

class

point

private

:

intx,y;

}; point::point(

int a,int b) //

定義建構函式

point::point(

const point &p)//

定義拷貝建構函式

void fun1(point p) //

形參是類point的物件p

point fun2()

//函式fun2()的返回值型別是point類型別

intmain()

執行結果:

using normal constructor

3040

using cpy constructor

6080

using cpy constructor

6080

using cpy constructor

6080

using normal constructor

using cpy constructor

2060

當沒有自定義的拷貝建構函式時的執行結果:

using normal constructor

3040

3040

3040

3040

using normal constructor

1030

//再舉乙個例項為:

#includeusing

namespace

std;

class

point

/*point::

*/point(const point &p) //

拷貝建構函式(用初始化過的物件為沒有初始化過的物件進行初始化)

point& operator = (const point &p)//

賦值運算子過載函式(用初始化過的物件為初始化過的物件進行賦值)

point fun();

void

print()

private

:

intx,y;

};point::point fun(point p4)

intmain()

物件複製和物件賦值

1 先看這個例子 include include using namespace std class student 建構函式 student string strname,int nage name strname age nage 帶引數的建構函式 student void show int m...

C 類物件的複製和賦值

例1.類物件複製,拷貝建構函式 includeusing namespace std class student void setname string str void getname private string m strname void student setname string str...

物件的賦值和複製

物件之間可以通過賦值運算子 進行賦值運算,通過以下的程式可以看出。include using namespace std class box box box int h,int w int len int box volume int main 說明 物件的賦值只對其中的資料成員進行賦值,而不對成員...