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
沒有留言:
張貼留言