Created
July 10, 2011 14:46
-
-
Save maraigue/1074589 to your computer and use it in GitHub Desktop.
クラスを使う意味(C++で説明)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <iostream> | |
// (いろいろと説明を省いている部分があります) | |
// 例えば、「皿」というクラスがあるとすると | |
class Dish{ | |
private: | |
// それが持つ変数(構造体のメンバに相当)として、例えば「食べ物の名前」や | |
// 「食べ物の量」が考えられる。 | |
// [補足1][補足2] | |
std::string food_name; | |
float food_weight; | |
public: | |
// また、皿に対して行う処理(メソッド)としては、「盛り付ける」や | |
// 「乗っているものを確認する」、「食べる」などが挙げられる。 | |
// [補足3] | |
// 「盛り付ける」の定義 | |
// 盛り付けに成功したらtrue, そうでなければfalseを返す。 | |
bool set(std::string new_name, float new_weight){ | |
// まだ皿に食べ物が残っていて、かつ別の食べ物を盛り付けようとすると失敗する | |
if(food_weight > 0.0 && food_name != new_name){ | |
return false; | |
} | |
// 盛り付ける | |
food_name = new_name; | |
food_weight += new_weight; | |
return true; | |
} | |
// 「乗っているものを確認する」の定義 | |
// (1) 乗っているものの名前を得る。 | |
std::string name(void){ | |
return food_name; | |
} | |
// (2) 乗っているものの量を得る。 | |
float weight(void){ | |
return food_weight; | |
} | |
// 「食べる」の定義 | |
// 食べた量を返す。 | |
float eat(float new_weight){ | |
float result; | |
// 指定した量だけ皿に食べ物が残っていなければ、残っている量をすべて食べる | |
if(food_weight < new_weight){ | |
result = food_weight; | |
food_weight = 0.0; | |
return result; | |
} | |
// そうでなければ、指定した量だけ食べる | |
food_weight -= new_weight; | |
return new_weight; | |
} | |
// またクラスには、初期化処理(コンストラクタ)や終了時処理(デストラクタ)を | |
// 定義することができる。ここではコンストラクタを使い、「初期状態の皿にある | |
// 食べ物の量は0である」という設定を行う。 | |
Dish(void){ | |
food_weight = 0.0; | |
} | |
}; | |
// これの何が便利かというと、「盛り付ける」や「食べる」という処理が | |
// 何に対する処理なのかを明示的に書くことができるのである。 | |
using namespace std; | |
int main(void){ | |
Dish my_dish; | |
// 例えば、「盛り付ける」については | |
// 「[盛り付けられる皿].set」というようにプログラムを書ける。 | |
my_dish.set("Konpeito", 200.0); | |
// 名前と量を取得するのも同様である。 | |
// [補足4] | |
cout << "[my_dish] Name: " << my_dish.name() << endl; | |
cout << "[my_dish] Weight: " << my_dish.weight() << endl; | |
// ここで、食べてから | |
my_dish.eat(20.0); | |
// 改めて名前と量を取得すると、ちゃんと量は「180.0」と表示される | |
// はずである。 | |
cout << "[my_dish] Name: " << my_dish.name() << endl; | |
cout << "[my_dish] Weight: " << my_dish.weight() << endl; | |
// クラスは構造体同様、別のクラスのインスタンス(実体)を定義すれば、 | |
// そちらでは値は完全に別に管理される。 | |
// [補足5] | |
Dish your_dish; | |
your_dish.set("Cake", 300.0); | |
// ↑こうしたからといって、my_dishの値は変わらない。 | |
cout << "[my_dish] Name: " << my_dish.name() << endl; | |
cout << "[my_dish] Weight: " << my_dish.weight() << endl; | |
return 0; | |
} | |
/* | |
補足(気になるところがあったら読んで下さい。詳しくはぐぐって下さい) | |
[補足1] | |
private, publicは | |
簡単に言うと、クラスの外側から見ることができるかどうかの違いです。 | |
例えばDish内のfood_nameはprivate指定なので、 | |
main内で「my_dish.food_name」のように呼び出すことは出来ません。 | |
[補足2] | |
std::stringは、C++標準添付の文字列クラスです。 | |
C言語の範疇では、文字列の表現には配列を使わないとなりませんでしたが、 | |
C++ではクラスがあるおかげで、いちいち配列を自分で定義しなくても | |
よくなりました。(文字列クラスの内部にすでに配列が定義されている) | |
[補足3] | |
メソッドの定義は、ここではクラス定義の内部にしていますが、 | |
C++では(基本的には)クラス定義の外部にするのが行儀のよい方法です。 | |
例えば以下のようになります。 | |
class Dish { | |
public: | |
// ここには、メソッドの型の定義だけ書く | |
bool set(std::string new_name, float new_weight); | |
}; | |
// 外部に実際の内容を定義する | |
bool Dish::set(std::string new_name, float new_weight){ | |
// | |
// この間省略 | |
// | |
} | |
[補足4] | |
coutは出力、endlは改行を意味します。 | |
printfやfprintfに代わる、C++の基本の入出力方法です。 | |
[補足5] | |
インスタンス別ではなく、1つのクラスで共通に利用される変数を定義する | |
方法もありますが、ここでは省略します。(「C++ static」でぐぐって下さい) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment