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 自定義拷貝建構函式的使用。
#includeusingnamespace
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 預設的拷貝建構函式
#includeusingnamespace
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
//再舉乙個例項為:
#includeusingnamespace
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 說明 物件的賦值只對其中的資料成員進行賦值,而不對成員...