1.構造函數
構造函數(constructor)是類(lèi)的一個(gè)特殊的成員函數,它與類(lèi)名同名。當定義該類(lèi)的對象時(shí),構造函數將被系統自動(dòng)調用用以實(shí)現對該對象的初始化。
構造函數不能有返回值,因而不能指定包括void在內的任何返回值類(lèi)型。
構造函數的定義與其他成員函數的定義一樣可以放在類(lèi)內或類(lèi)外。
構造函數的定義格式為
類(lèi)名(形參說(shuō)明)
{函數體}
構造函數既可以定義成有參函數,也可以定義成無(wú)參函數,要根據問(wèn)題的需要來(lái)定。
注意:程序中不能直接調用構造函數,構造函數是在創(chuàng )建對象時(shí)由系統直接調用的,因此,在構造函數中一般完成初始化類(lèi)成員變量的操作。
2.構造函數的重載
一個(gè)類(lèi)中出現了兩個(gè)以上的同名的成員函數時(shí),稱(chēng)為類(lèi)的成員函數的重載。
在類(lèi)的成員函數的重載中,比較常見(jiàn)形式是構造函數的重載,當類(lèi)中出現了重載構造函數時(shí),C++語(yǔ)言將根據構造函數中的參數個(gè)數和類(lèi)型選擇合適的構造函數來(lái)完成對象的構造。
3.默認構造函數與缺省參數的構造函數
如果在類(lèi)中沒(méi)有顯示定義構造函數,則編譯系統會(huì )為該類(lèi)提供一個(gè)默認的構造函數,該默認構造函數是一個(gè)無(wú)參函數,函數體為空,它僅僅負責創(chuàng )建對象,而不做任何初始化工作(即不給相應的數據成員賦初值),所以在該類(lèi)的對象創(chuàng )建時(shí)不能保證有一個(gè)確定的初始狀態(tài)。
良好的編程習慣應該是給類(lèi)提供合適的完成初始化工作的構造函數。
但是,只要一個(gè)類(lèi)定義了一個(gè)構造函數(不一定是無(wú)參構造函數),編譯系統就不再提供默認的構造函數。
當構造函數具有缺省參數時(shí),稱(chēng)為具有缺省參數的構造函數,在使用具有缺省參數的構造函數時(shí),要防止二義性。
4.拷貝構造函數
拷貝構造函數是一種特殊的構造函數。定義拷貝構造函數的一般格式為
類(lèi)名::類(lèi)名(const 類(lèi)名 &形式參數)
{ 函數體 }
拷貝構造函數的函數名與類(lèi)名同名。該函數也沒(méi)有返回值。
拷貝構造函數的功能是通過(guò)將一個(gè)同類(lèi)對象的值拷貝給一個(gè)新對象,來(lái)完成對新對象的初始化,即用一個(gè)對象去構造另外一個(gè)對象。
如果在類(lèi)的定義中沒(méi)有定義拷貝構造函數,則編譯系統將自動(dòng)生成一個(gè)具有上述形式的默認的拷貝構造函數,作為該類(lèi)的公有成員。
5.析構函數
與構造函數對應的是析構函數。當一個(gè)對象被定義時(shí),系統會(huì )自動(dòng)調用構造函數為該對象分配相應的資源,當對象使用完畢后且在對象消失前,系統會(huì )自動(dòng)調用類(lèi)的析構函數來(lái)釋放這些系統資源。
析構函數也是類(lèi)的一個(gè)特殊的成員函數,其函數名稱(chēng)是在類(lèi)名的前面加上“~”;它沒(méi)有返回值,也沒(méi)有參數。一個(gè)類(lèi)中只能擁有一個(gè)析構函數,所以析構函數不能重載。
析構函數的定義方式為
~類(lèi)名()
{ 函數體 }
如果程序員在定義類(lèi)時(shí)沒(méi)有為類(lèi)提供析構函數,則系統會(huì )自動(dòng)創(chuàng )建一個(gè)默認的析構函數,其形式為
~類(lèi)名()
{ }
對象被析構的順序與其創(chuàng )建時(shí)的順序正好相反,即最后構造的對象最先被析構。
如果一個(gè)對象是被new運算符動(dòng)態(tài)創(chuàng )建的,當使用delete運算符釋放它時(shí),delete將會(huì )自動(dòng)調用析構函數。
6.一個(gè)類(lèi)的對象作為另一個(gè)類(lèi)的數據成員
當一個(gè)類(lèi)中的數據成員是某一個(gè)類(lèi)的對象時(shí),可稱(chēng)這種成員是新建類(lèi)的子對象或對象成員,則新類(lèi)的定義格式可表示為
calss X
{
類(lèi)名1 成員名1;
類(lèi)名2 成員名2;
類(lèi)名3 成員名3;
……………
類(lèi)名n 成員名n;
…。………… //其他成員
};
其中,X為新建類(lèi)的類(lèi)名,類(lèi)名1、類(lèi)名2、……、類(lèi)名n必須是已定義過(guò)的類(lèi)。如
class A {};
class B
{
A a;
};
則在創(chuàng )建類(lèi)B的對象(調用類(lèi)B的構造函數)時(shí),會(huì )自動(dòng)調用類(lèi)A的構造函數。如果類(lèi)A的構造函數為有參函數時(shí),通常采用初始化表的方式來(lái)調用構造函數。
新類(lèi)的構造函數的一般定義格式為
新類(lèi)(參數表0):成員1(參數表1),成員2(參數表2),…,成員n(參數表n)
{ ………… }
其中,成員1、成員2、……、成員n是新類(lèi)中的對象成員;參數表1提供初始化成員1所需的參數,參數表2提供初始化成員2所需的參數,依此類(lèi)推,并且這幾個(gè)參數表中的參數均來(lái)自參數表0.另外,初始化新類(lèi)的非對象成員所需的參數,也由參數表0提供。
7.常對象與常對象成員
(1)常對象
常對象是指對象常量,其定義格式為
const 類(lèi)名 對象名;
從格式中可以看出,常對象的定義與一般對象的定義相比,在類(lèi)名前必須加const關(guān)鍵字。
常對象具有以下特點(diǎn)
l 常對象在定義時(shí)必須進(jìn)行初始化,而且在程序中不能再對其進(jìn)行更新。
l 通過(guò)常對象只能調用類(lèi)中的常成員函數,而不能調用類(lèi)中的其他成員函數。
(2)常對象成員
常對象成員分為常成員函數和常數據成員。
1)常成員函數
在類(lèi)中,使用關(guān)鍵字const說(shuō)明的成員函數成為常成員函數,常成員函數的說(shuō)明格式為
類(lèi)型 函數名(形參表) const;
類(lèi)中的常成員函數與普通成員函數相比,具有以下特點(diǎn)
l 常成員函數為類(lèi)的只讀函數,這種成員函數可以讀取數據成員的值,但不可以更新數據成員的值,它也不能調用該類(lèi)中沒(méi)有const修飾的其他成員函數。
l 常成員函數定義中的const關(guān)鍵字是函數類(lèi)型的一部分,因此在其實(shí)現部分中也要帶上const關(guān)鍵字。
l 常成員函數定義中的const關(guān)鍵字可以參與區分重載函數。
例如:
| #include <iostream.h> class Test_const{ void Test_const::setvalue(int newvalue) void main() |
2)常數據成員
類(lèi)中定義的數據成員,除了可以為一般變量外,還可以為const常量,這種數據成員稱(chēng)為常數據成員。
構造函數可以對對象的數據成員進(jìn)行初始化,但如果數據成員為常量成員或引用成員時(shí),則不能在構造函數中直接用賦值語(yǔ)句為其進(jìn)行賦值。需要利用構造函數所附帶的初始化表進(jìn)行初始化,即在構造函數的括號后面加上“:”和初始化表,其格式為
類(lèi)名::類(lèi)名(形參表):常數據成員名1(值1),常數據成員名2(值2),……
{
//構造函數的函數體
}
可以看出,當有多個(gè)數據成員時(shí),初始化表中的初始化項有多個(gè),且需要用逗號隔開(kāi)。
8.類(lèi)作用域
類(lèi)作用域又可稱(chēng)為類(lèi)域,它是指在類(lèi)定義中用一對大括號開(kāi)括起來(lái)的范圍。
不同的類(lèi)的成員函數可以具有相同的名字,因此,需要用作用域運算符“::”來(lái)指明該成員函數所屬的類(lèi)。
在類(lèi)的成員函數中可以直接引用類(lèi)的數據成員。但是,如果在成員函數中定義了同名的局部變量時(shí),則必須用作用域運算符“::”來(lái)指定,以免混亂。例如:
| #include <iostream.h> class Region{ private: int x; int y; public: Region(int x,int y) { Region::x=x; Region::y=y; } void print() { cout<<"x="<<x<<",y="<<y<<endl; } }; void main() { Region region(5,10); Region *p; p=®ion; region.print(); p->print(); } |
聯(lián)系客服