對象的賦值
如果對一個類定義了兩個或多個對象,則這些對象之間是可以進行賦值,或者說,一個對象的值可以賦值給另一個同類的對象。這里所指的值是指對象中所有數 據的成員的值。對象之間進行賦值是“=”進行的,對象賦值的形式如下:
對象名1=對象名2;
#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,20,25),box2;
cout<<"1"<<box1.volume()<<endl;
box2=box1;
cout<<"1"<<box2.volume()<<endl;
return 0;
}
1.對象的賦值只對其中的數據成員賦值,而不能對成員函數賦值。賦值的過程是將一個對象的數據成員在存儲空間的狀態復制給另一個對象的數據成員的存 儲空間。
2.類的數據成員中不可包括動態分配的數據,否則在賦值時可能出現嚴重的后果。
對象的復制
有時會需要用到多個完全相同的對象,所以需要復制。有時需要將對象在某一瞬間時的狀態保留下來。這就是更需要復制。用一個已有的對象快速的復制出 多個完全相同的對象。如:
Box box2(box1);
其作用就是用已有的對象box1去克隆出新對象box2.
其一般形式為:類名 對象名2(對象1);在建立一個新對象時調用一個特殊的構造函數----復制構造函數,這個函數的形式如下:
Box::Box(const Box& b)
{
height=b.height;
width=b.width;
length=b.length;
}
復制構造函數也是構造函數,但是它只有一個參數,這個參數是本類的對象(不能是其他類對象)。此復制構造函數的作用就是將實參對象的各個數據成員值一一賦值給新的對象中對應的數據成員。
C++還提供了另一種語句來復制對象: Box box2=box1; 其基本形式如下:
類名 對象名1=對象名2;
還可以進行多個對象的賦值:Box box2=box1,box3=box2;請與下面的定義語句作比較:
int a=4,b=a;這種形式看起來很直觀,但是用起來很方便,但是其作用就是調用復制構造函數。
注意:賦值和復制的區別,對象的賦值是對已經存在的對象賦值,因此必須先定義被賦值的對象,才能進行賦值。而對象的復制則是從無到有的建立一個對象,並使它與一個已有的對象完全相同(包括結構和值)。
普通構造函數與復制構造函數的區別:
1.在形式上,
類名(形參列表); //普通構造函數的聲明,如Box(int h,int w,int len);
類名(類名 &對象名); //復制構造函數的聲明,如Box(Box &b);
2.在建立對象時,實參類型不同。系統會根據實參的類型決定調用普通構造函數或復制構造函數。
Box box1(12,15,16); //實參為整數,調用普通的構造函數
Box box2(box1); //實參是對象名,調用復制構造函數
3.在什么情況下被調用。
普通構造函數在程序中建立對象時被調用。
復制構造函數在已有對象復制一個新對象時被調用,一下3種情況需要克隆對象;
1.程序中需要建立一個對象,並用另一個同類的對象對她初始化
2.當函數的參數為類的對象時,在調用函數時需要將實參對象完整的傳遞給形參,也就是需要建立一個實參的拷貝,這就是按實參復制一個形參,系統是 通過調用復制構造函數來實現的,這樣能保證形參具有和實參完全相同的值。
靜態數據成員
靜態數據成員是各個對象所共有,而不是只屬於某個對象成員,所有對象都可以引用他們。靜態數據成員在內存中僅僅占一份空間。每個對象都可以引用這個靜態數據成員。靜態數據成員的值對所有對象都是一樣的。如果改變它的值,則在各個對象中的這個數據成員的值同時改變。
靜態數據成員可以初始化,但是只能在類體外進行初始化。
int Box::height=10; //表示對Box類中的數據成員初始化
數據類型 類名::靜態數據成員名=初值; 不必在初始化語句中加static.不能用參數初始化表對數據成員初始化。像:
Box (int h,int w,int len):height(h){}這是不對的,height是靜態數據成員。
靜態成員函數
靜態成員函數是類的一部分,但是不是對象的一部分。如果要在類外調用公用的靜態成員函數,要用類名和域運算符“::”,如
Box::volume();也可以通過對象名調用成員函數,a.volume();但是這並不意味着此函數屬於對象a的,而只是用a的類型而已。
記住:靜態成員函數不屬於對象,它與任何對象都是無關的,因此靜態成員函數沒有this指針。也就是說:非靜態成員函數有this指針,而靜態成員函數沒有this指針。由此決定了靜態成員函數不能訪問本類中的非靜態成員。靜態成員函數可以直接引用本類中的靜態數據成員。因為靜態數據成員同樣屬於類的,可以直接引用。
並不是絕對不能訪問本類中的非靜態成員,只是不能進行默認訪問,因此無法知道應該去找哪個對象,如果非要引用本類中的非靜態成員,應該加對象和成員運算符“.”。 例如:cout<<a.width<<endl;