C++ 再入門 その5 クラスって何?
C言語が古典的なプログラミング言語で高級言語というよりは中級言語、いや低級言語だと揶揄する人もいますが、それに対してC++はオブジェクト指向言語であるという説明もチラホラ見かけます。C++のC++らしい機能の代表がクラスであり、クラスを使うことでオブジェクト指向なコードが書けるという理屈なのですが、そもそもクラスであるとかオブジェクトって一体何なのでしょうか。
まずは基本的な考え方から始めると、商品についてのプログラムを作ろうとすれば、関連する情報をひとまとめにした変数があればコードがわかりやすくなります。例えば商品には
商品名(63文字以内)
単価(正の整数)
商品コード(7文字以内)
があるとします。これを
char produt_name[64];
unsigned int product_price;
char product_sku[8];
と、それぞれを変数に割り当ててproduct_と同じ名前で始めることで関連があることを示すよりは
struct product {
char name[64];
unsigned int price;
char sku[8];
};
という定義をして、以下のように初期化するなどして
struct product pd = {”pencil”, 30, “P001002”};
と構造体を使ってひとつの変数で、pd.name、pd.price、pd.skuという形で使ったほうが、確実に関連したものとして扱うことができます。そして商品情報を使って処理をする関数を書くのであれば、引き数や戻り値にこの構造体を使った関数をひとつずつ書いていくのですが、関連する関数をまとめる仕組みはありません。
ここまでがC言語でのアプローチです。
C++では、このような時にクラスというものを作ることができます。
#include <iostream>
#include <string>
using namespace std;
class product {
public:
string name;
unsigned int price;
string sku;
};
void main() {
product pd;
pd.name = "pencil";
pd.price = 30;
pd.sku = "P001002";
cout << pd.name << “,” << pd.price << “,” << pd.sku << endl;
}
このようにクラスを定義して、それを使った処理を書きます。
ほぼ構造体と同じような書き方ででクラスを定義して使うことが出来ます。ここで急にstringとかが出てきますが、これはC++で登場した文字列を扱う標準的な型です。もう長さを気にすることもありません。
これだけだと構造体と違わないのではないかとも見えますが、C++ではクラスに変数だけではなく関数を書くことも出来るのです。例えば商品の情報を分かりやすい形式で出力するクラスを作るのであれば、
void repr(void) {
cout << name << “,” << price << “,” << sku << endl;
}
といった関数をクラス定義に書けば、
pd.repr();
というクラス関数を呼び出すことで
という出力を得ることができます。
#include <iostream>
#include <string>
using namespace std;
class product {
public:
void repr(void) {
cout << name << “,” << price << “,” << sku << endl;
}
string name;
unsigned int price;
string sku;
};
void main() {
product pd;
pd.name = "pencil";
pd.price = 30;
pd.sku = "P001002";
pd.repr();
}
クラスの説明として先にオブジェクトの話から始まることも多いのですが、なかなかわかりにくい概念なので、まずは構造体の親戚くらいに思っていれば構わないです。大きな違いは構造体がデータのみを管理するのに対して、クラスはデータを操作する関数も同時に定義できるという点です。もちろんクラスの機能はこれだけに留まらず、他にもいろいろな違いはあります。
プログラミング言語の進化の中で古典的言語からC言語辺りまでは、構造化を掲げて進化してきたのですが、それはあくまでいかに手順を理解しやすく記述できるかという話です。手順は手順、データはデータです。C++ではSmalltalkなどの影響も受けてデータが中心となり、こんなデータに対しては、こんな手順を使うという書き方が出来るようになりました。ですから、普通に手順を書いていっても、その具体的な手順はデータによって異なる処理をするんだよという書き方が簡潔にできるようになりました。
そんな事を言われても、実際にその恩恵を感じるには、いろいろなコードを書いてみなければなかなかわからないのかもしれませんが、その効果は大変に大きく、また、データの構造から手順を書いていくというのは発想の転換も必要で、クラスを上手にオブジェクトとして扱う方法を理解できるようになれば、プログラミングの新しい世界も開けてきます。始めて勉強した時には「エウレカ!」というか、天動説から地動説に鞍替えしたと言うか、なかなか感動したものです。
次回は、そんなクラスのアレコレをもう少し追っていくことにします。
ヘッダ画像は、以下のものを使わせていただきました。
https://commons.wikimedia.org/wiki/File:ISO_C%2B%2B_Logo.svg
Jeremy Kratz - https://github.com/isocpp/logos, パブリック・ドメイン, https://commons.wikimedia.org/w/index.php?curid=62851110による