|
class是C++中用來封裝資料的關鍵字,當您使用類別來定義一個物件(Object)時,您考慮這個物件可能擁有的「屬性」(Property)與
「方法」(Method),屬性是物件的靜態描述,而方法是可施加於物件上的動態操作,您使用類別定義出這個物件的規格書,之後就可依這個規格書製作出一
個個的物件實例,並在製作過程中設定個別物件的專屬特性資料。 舉個例子來說,您可以定義一個「球」的模子,考慮球有各種不同的顏色(或名稱),以及球最基本的球半徑資訊,您想到這些資訊應該可以取得,並可以進一步取 得球的體積,當您在C++中要包裝這些資訊時,您可以如下進行定義:
#include <string> 您在表頭檔案中定義類別,表頭檔案的名稱建議與類別名稱同名,一個定義良好的類別,即使在不看程式碼實作的情況下,也可以從定義中看出這個類別的大致功 能;class是C++中用來定義類別的關鍵字,Ball是我們取得類別名稱,記得一個類別的定義是這麼作的: class
Ball {
// 成員定義 }; 最重要的是別忘了在最後加上分號,初學C++的新手很常犯這個錯誤;接下來定義類別的成員,注意到public這個關鍵字,它表示以下所定義的成員可以使 用物件名稱直接被呼叫,也稱之為「公用成員」或「公開成員」,private關鍵字下的則是「私用成員」或「私有成員」,不可以透過物件名稱直接呼叫。 在類別封裝時,有一個基本原則是:資訊的最小化公開。如果屬性可以不公開就不公開,如果要取得或設定物件的某些屬性,也是儘量透過方法成員來進行。 資訊的最小化公開原則是基於安全性的考量,避免程式設計人員隨意操作屬性成員而造成程式的錯誤,您可以在日後的程式設計中慢慢來體會;在稍後的實作中,您 將可以看到,我將不會radius與name兩個私用成員直接進行存取,而是透過公開的方法來進行設定。 接下來實作類別的內容:
#include <string> 類別的實作檔案通常與類別名稱同名,如此例中的Ball.cpp,與類別名稱同名的方法稱之為「建構函式」(Constructor),也有人稱之為「建 構子」,它沒有傳回值,建構函式的作用在於物件生成時自動初始一些必要的資訊,它可以被過載,以滿足物件生成時不同的設定條件。 「::」稱之為類別範圍解析(Class scope resolution)運算子,在實作類別方法時,在::之前指明您要實作的是哪一個類別的方法,您在實作中過載了建構函式,在不指定引數的情況下,會將 radius設定為0,而name設定為"noname ball",另兩個建構函式則可以指定引數,無參數數建構函式是預設建構函式,如果您沒有定義預設建構函式,則編譯器會自動幫您產生一個無實作內容的預設 建構函式。 定義好類別之後,您就可使用這個類別來建立物件,例如: Ball
ball1;
Ball ball2(5.0, "black ball"); string name("yellow ball"); Ball ball3(10.0, name); 也可以這麼建立物件: Ball
ball1 = Ball(5.0,
"black ball");
這有些類似宣告變數,使用類別建立的變數稱其為「物件」(Object)或「實例」(Instant),在上例中就是ball1、ball2與ball3 三個物件,ball1物件在建立時並不指定任何參數,所以根據之前實例建構函式的內容,b1的radius將設定為0.0,name設定為"noname ball";ball2則給定兩個參數,所以ball2的radius設定為5.0,而ball2的name設定為"black ball";ball3則是給定radius引數為10.0,第二個參數則給定string實例。 您可以透過公開成員來操作物件或取得物件資訊,方法是使用物件名稱加上「.」運算子,例如: ball1.name("green
ball");
cout
<<
ball1.name() << endl;
以下是使用Ball類別的一個實際例子:
#include <iostream> 執行結果:
對於簡單的成員函式,您可以將之實作於類別定義中,在類別定義中即實作的函式會自動成為inline函式,例如:
#include <string>
#include <string> 在定義類別時,如果您只是需要使用到某個類別來宣告指標或是參考,但不涉及類別的生成或操作等訊息,則您可以作該類別的前置宣告(Forward declaration),而不用含入該類別的定義,例如:
class Ball; 在定義Test類別時,您尚未真正使用Ball來建構物件進行操作,您只是用它來宣告一些名稱,則您只要使用前置宣告就可以了,實際實作類別時再含入 Ball.h表頭檔即可,例如:
#include "Test.h" 如果您的類別定義有單一參數的建構函式(或除了第一個參數之外,其它參數都有預設值的建構函式),則預設會有自動轉換的作用,例如: class
Ball {
public: Ball(const char*); ... }; 則您可以使用以下的方式來建構物件並初始化: Ball
ball = "Green
ball";
預設的轉換行為是由編譯器施行的,但有時是有危險的,如果您不希望編譯器自作主張,則您可以使用explicit修飾,告訴編譯器不要自作主張: class Ball { public: explicit Ball(const char*); ... }; |