10-3 如何建立複雜的類別
一、成員函數可以定義在 class 之外
我們可以只在 class body 中 宣告 member function,再將它 定義 在 class body 之外。
class sprite {
private:
string name;
public:
sprite(string _name); // 只有宣告
string getName(); // 只有宣告
};
// 定義 sprite 類別的 sprite 成員函數
sprite::sprite(string _name)
{
name = _name;
}
// 定義 sprite 類別的 getName 成員函數
string sprite::getName()
{
return name;
}
以下是一個遊戲中角色的範例
#include <iostream>
using namespace std;
class sprite
{
private:
string name;
string status;
int HP;
int maxHP;
void setStatus(void); // 根據 hp 設定健康狀態
void drawHpBar(void); // 繪製 hp 長條圖
public:
sprite(string _name);
string getName(); // 取得姓名
void decHP(int n); // 減少 HP
void addHP(int n); // 增加 HP
void show(void); // 顯示狀態
};
void sprite::setStatus(void)
{
if(HP >= maxHP *0.9)
status = "健康";
else if(HP >= maxHP *0.6)
status = "受傷";
else if(HP >= maxHP *0.3)
status = "重傷";
else if(HP > 0)
status = "瀕死";
else
status = "死亡";
}
sprite::sprite(string _name)
{
name = _name;
HP = maxHP = 20;
status = "健康";
}
string sprite::getName()
{
return name;
}
void sprite::decHP(int n)
{
HP = HP - n;
if(HP <0)
HP = 0;
setStatus();
}
void sprite::addHP(int n)
{
HP = HP + n;
if(HP > maxHP)
HP = maxHP;
setStatus();
}
void sprite::drawHpBar(void)
{
int a = 10*HP/maxHP;
cout << "[";
for(int i=0; i<a; i++)
cout << "#";
for(int i=a; i<10; i++)
cout << "-";
cout << "] ";
}
void sprite::show(void)
{
cout << "[" << name << "] ";
cout << "狀態:" << status << endl;
drawHpBar();
cout << "HP: " << HP << "/" << maxHP << endl;
cout << endl;
}
void attack(sprite &s, int n)
{
cout << s.getName() << " 受到 " << n << " 點的傷害。" << endl;
cout << endl;
s.decHP(n);
}
int main()
{
sprite fighter1("David");
fighter1.show();
attack(fighter1, 6);
fighter1.show();
attack(fighter1, 6);
fighter1.show();
attack(fighter1, 6);
fighter1.show();
attack(fighter1, 6);
fighter1.show();
return 0;
}
David 受到 6 點的傷害。
[David] 狀態:受傷 [#######---] HP: 14/20
David 受到 6 點的傷害。
[David] 狀態:重傷 [####------] HP: 8/20
David 受到 6 點的傷害。
[David] 狀態:瀕死 [#---------] HP: 2/20
David 受到 6 點的傷害。
[David] 狀態:死亡 [----------] HP: 0/20
二、將類別放在獨立的檔案中
在前一個例子裡,我們把 sprite 類別和 main 放在同一個檔案裡,在程式碼短的情形下是沒問題的。但在動輒使用到數十乃至上百個類別的程式裡,這麼做就不切實際了,會造成維護和分工上的困擾。
我們可以將sprite類別移到獨立的檔案裡,這樣修改 sprite 時就可以專注在 sprite 的程式碼,main.cpp 裡也不會顯得凌亂,建置專案時的效率也會更好。
sprite.h
#ifndef SPRITE_H_INCLUDED
#define SPRITE_H_INCLUDED
#include <iostream>
using namespace std;
class sprite
{
private:
string name;
string status;
int hp;
int maxHp;
void setStatus(void); // 根據 hp 設定健康狀態
void drawHpBar(void); // 繪製 hp 長條圖
public:
sprite(string _name);
string getName(); // 取得姓名
void decHP(int n); // 減少 HP
void addHP(int n); // 增加 HP
void show(void); // 顯示狀態
};
#endif // SPRITE_H_INCLUDED
sprite.cpp
#include "sprite.h"
void sprite::setStatus(void)
{
if(HP >= maxHP*0.9)
status = "健康";
else if(HP >= maxHP*0.6)
status = "受傷";
else if(HP >= maxHP*0.3)
status = "重傷";
else if(HP > 0)
status = "瀕死";
else
status = "死亡";
}
sprite::sprite(string _name)
{
name = _name;
HP = maxHP = 20;
status = "健康";
}
string sprite::getName()
{
return name;
}
void sprite::decHP(int n)
{
HP = HP - n;
if(HP<0)
HP = 0;
setStatus();
}
void sprite::addHP(int n)
{
HP = HP + n;
if(HP > maxHP)
HP = maxHP;
setStatus();
}
void sprite::drawHpBar(void)
{
int a = 10*HP/maxHP;
cout << "[";
for(int i=0; i<a; i++)
cout << "#";
for(int i=a; i<10; i++)
cout << "-";
cout << "] ";
}
void sprite::show(void)
{
cout << "[" << name << "] ";
cout << "狀態:" << status << endl;
drawHpBar();
cout << "HP: " << HP << "/" << maxHP << endl;
cout << endl;
}
main.cpp
#include <iostream>
#include "sprite.h"
using namespace std;
void attack(sprite &s, int n)
{
cout << s.getName() << " 受到 " << n << " 點的傷害。" << endl;
cout << endl;
s.decHP(n);
}
int main()
{
sprite fighter1("David");
fighter1.show();
attack(fighter1, 6);
fighter1.show();
attack(fighter1, 6);
fighter1.show();
attack(fighter1, 6);
fighter1.show();
attack(fighter1, 6);
fighter1.show();
return 0;
}
建置時的檔案相依性
