C++宣告類別(class)的方式如下。
Class類似struct為多種資料型態的組合成的新型態,但除了資料成員(屬性)還可包含函式成員(方法)。
宣告類別 declare class
宣告類別的語法如下:
class
- 宣告類別的關鍵字。ClassName
- 類別名稱,習慣以大駝峰命名UpperCamelCase
。access_specifier_1-2
- 存取修飾符(access specifier),分為public
、protected
、private
。若無存取修飾符則預設為private
。member1-2
- 類別成員,分為屬性及方法:- 屬性(attributes) - 即資料成員,用來儲存物件的資料狀態。
- 方法(methods) - 即函式成員,用來改變或取得物件的資料狀態。˙
class ClassName {
access_specifier_1:
member1;
access_specifier_2:
member2;
...
}
下面宣告一個類別Car
中有private
及public
存取修飾符。
private
修飾屬性model
、speed
;
public
修飾建構式Car()
、Car(string model, int speed)
及方法GetModel()
、GetSpeed()
、SpeedUp()
、SlowDown()
。
main.cpp
#include <string>
using namespace std;
class Car {
private:
// 屬性 attributes
string model;
int speed;
public:
// 建構式 constructors
Car() { speed = 0; }
Car(string model, int speed) : model(model), speed(speed) {}
// 方法 methods
string GetModel() { return model; }
int GetSpeed() { return speed; }
void SpeedUp() { speed++; }
};
成員存取修飾符 member access specifiers
成員存取修飾符的用途為控制成員是否能從類別外存取:
public
- 成員可在類別外、繼承類別、類別內存取。protected
- 成員可在繼承類別、類別內存取。private
- 成員僅可在類別內存取。
例如GetModel()
方法為public
,所以可以在類別外存取;而model
屬性為private
則在類別外存取時編譯會發生錯誤。
main.cpp
#include <iostream>
#include <string>
using namespace std;
class Car {
private:
string model;
int speed;
public:
Car() { speed = 0; }
Car(string model, int speed) : model(model), speed(speed) {}
string GetModel() { return model; }
int GetSpeed() { return speed; }
void SpeedUp() { speed++; }
};
int main() {
Car car{"MAZDA CX-30", 0};
cout << car.GetModel() << endl;
cout << car.model << endl; // error: 'speed' is a private member of 'Car'
return 0;
}
方法 methods
C++定義類別的方法有兩種方式,一是在類別中直接定義方法及主體,例如上例;一是在類別中僅定義方法原型(prototype),即僅定義方法名稱、參數型態及數量、回傳型態,然後在類別外定義同方法原型簽章的函式為方法主體,並在函式名稱前加上同類別名稱的作用範圍符(scope operator)Car::
。
例如下面將建構式及方法主體定義在類別外的函式。
main.cpp
#include <string>
using namespace std;
class Car {
private:
string model;
int speed;
public:
// 建構式原型
Car();
Car(string model, int speed);
// 方法原型
string GetModel();
int GetSpeed();
void SpeedUp();
};
// 建構式主體
Car::Car() { speed = 0; }
Car::Car(string model, int speed) : model(model), speed(speed) {}
// 方法主體
string Car::GetModel() { return model; }
int Car::GetSpeed() { return speed; }
void Car::SpeedUp() { speed++; }
建構式 constructors
建構式是一種特別的方法,用來建立新的類別物件並初始化屬性。建構式的名稱必須與類別名稱相同,且沒有任何返回型態。
例如下面定義了兩個Car
的建構式Car()
及Car(string model, int speed)
,如函式一樣建構式也可重載(overloading)。
無參數的建構式為預設建構式(default constructor),所以Car()
為預設建構式。當宣告類別的物件變數時若無初始化敘述(Car car;
)、或為空的統一初始化(uniform initialization)敘述(Car car = {};
)則呼叫預設建構式來建立物件。
main.cpp
#include <iostream>
#include <string>
using namespace std;
class Car {
private:
string model;
int speed;
public:
Car() { speed = 0; } // 預設建構式
Car(string model, int speed) : model(model), speed(speed) {}
string GetModel() { return model; }
int GetSpeed() { return speed; }
void SpeedUp() { speed++; }
};
int main() {
Car car1; // 呼叫預設建構式
cout << car1.GetModel() << endl; // "" (空字串)
cout << car1.GetSpeed() << endl; // 0
Car car2 = {}; // 呼叫預設建構式
cout << car2.GetModel() << endl; // "" (空字串)
cout << car2.GetSpeed() << endl; // 0
Car car3 = {"MAZDA CX-30", 1}; // 呼叫有參數的建構式
cout << car3.GetModel() << endl; // MAZDA CX-30
cout << car3.GetSpeed() << endl; // 1
return 0;
}
若無建構式進行初始化建立物件,則物件中某些型態的屬性會是任意值。例如下面把建構式移除,則宣告的car
物件的speed
是不確定的整數值。
main.cpp
#include <iostream>
#include <string>
using namespace std;
class Car {
private:
string model;
int speed;
public:
string GetModel() { return model; }
int GetSpeed() { return speed; }
void SpeedUp() { speed++; }
};
int main() {
Car car;
cout << car.GetSpeed() << endl; // -343938976 (不確定的整數值)
return 0;
}
範例
下面在主程式以統一初始化語法調用建構式Car(string model, int speed)
初始化屬性model
的值為"MAZDA CX-30"、speed
值為0,建立了一個Car
類別的物件car
。
接著呼叫car.SpeedUp()
增加速度。然後調用car.GetModel()
取得car.model
印出,調用car.GetSpeed()
取得car.speed
印出。
main.cpp
#include <iostream>
#include <string>
using namespace std;
class Car {
private:
string model;
int speed;
public:
Car() { speed = 0; }
Car(string model, int speed) : model(model), speed(speed) {}
string GetModel() { return model; }
int GetSpeed() { return speed; }
void SpeedUp() { speed++; }
};
int main() {
Car car{"MAZDA CX-30", 0};
car.SpeedUp();
cout << car.GetModel() << endl; // MAZDA CX-30
cout << car.GetSpeed() << endl; // 1
return 0;
}
執行後印出以下。
MAZDA CX-30
1
沒有留言:
張貼留言