第2章 第1節 クラスとは


← 前に戻る | 次に進む →

この節では、まずオブジェクト指向プログラミングにおいて大事な役割を果たすクラスについての解説をします。しかしその前に、オブジェクト指向について簡単に説明しましょう。

オブジェクト指向のオブジェクトとは、日本語訳すれば物とか物体といったような意味になるでしょう。つまり、非常に簡略化した言い方をすれば、オブジェクト指向とはそれぞれ独立した物を組み合わせるという発想が原点になります。

例えば、テレビを思い描いてください。テレビはスイッチを入れれば画面が映ってそれを見ることができますよね。そして、それはテレビという一つの物です。しかし注意してテレビを観察すると、テレビはブラウン管やらアンテナやらの物でできているのがわかります。だからといって、テレビを見るときにはそれらのことはまったく考える必要はないですよね。

つまり、ブラウン管やアンテナなどのような部品を組み合わせてテレビを作るように、プログラムもそれぞれの部品(プログラム)を組み合わせて作ることができるはずです。そうすれば、プログラムを拡張するときには部品を加えたり、一部の部品だけ改良するだけで済むわけです。これがオブジェクト指向プログラミングになります。

ではその物や部品をプログラムの中で定義するためにはどうすればよいのでしょうか? そこでクラスが出てくるわけです。これからそのクラスについて述べていきます。

まずここでは、ノートのクラスを作ってみることにしましょう。ノートといえば、まず文章などを書くスペースが必要です。そしてそのスペースに対して読み書きができなくてはいけません。まずはそれをクラスで表してみましょう。

List 2.1 ノートクラス

#include <iostream>
#include <string>
using namespace std;

// ノートクラス.
class Notebook {
private:
    string note;  // ノートの本文.

public:
    string Read(void) const;  // ノートを読む.
    void Write(string);       // ノートに書く.
};

まずここでは、ノートの読み書きを行うスペースとして、string型のnoteを定義しました。つまりこの変数noteに対して読み書きを行うのです。そしてその読み書きを行うために関数ReadとWriteを宣言しました。もちろんReadでnoteに書かれた文を読み、Writeでnoteに書き込むわけです。因みにクラスで宣言した変数のことをメンバ変数、関数のことをメンバ関数と呼びます。そして、このグラス自体をNotebookと定義しています。

観察力の鋭い方なら、クラスの中にあるprivateとpublicって何? と思われることでしょう。クラスにおいてこのprivateとpublicはとっても重要なものなんです。privateで宣言されている変数や関数は、同じクラスのメンバ関数からしか読み書きできません。つまり、別のクラスやグローバル関数などからはアクセスできないのです。このような制限を掛けることによって誤って変更されたりすることを防げます。そしてお察しの通り、publicで宣言された変数や関数はどこからでも自由に読み書きできます。

そして、このアクセス制限をより確かなものにするために、ノートクラスのRead関数は後ろにconstを付けています。このconstはRead関数内ではこのクラスのメンバ変数を変更できないことを示しています。ノートを読んでいるときにそのノートの内容が変わってしまうと困りますよね。つまり、そうなることを防いでいるのです。

classとstruct

C言語でもおなじみのstruct(構造体)。もちろんC++でもありますが、classとはどのように違うのでしょうか? classではメンバ関数が使えるけどstructでは使えないでしょとか、structではprivateとかpublicとかがないよ、などと返ってくるかもしれませんが、それはCでのお話で、このどちらもC++では使えるのです。

では、C++ではclassとstructはまったく同じなのかといえばそうとも言えません。もちろんまったく同じことはできますが、classはデフォルトでprivateになっており、structはpublicになっているのです。この節のList 2.1では、クラスの最初にprivate:と書きましたが、classはデフォルトでprivateなので省略することもできるのです。別の言い方をすれば、すべてprivateとpublicを明示的に示してあればclassでもstructでもプログラムの動作としてはまったく同じように使えるわけです。

しかし、だからどちらを使ってもまったく差支えがないということはなく、プログラムソースはコンピュータだけでなく人も読むものですから、できるだけわかり易くしておくことが肝要です。だから、クラスとして使用するところはちゃんとclassで定義し、C言語の構造体のような使い方の時にはstructを使用すると良いでしょう。

では、このノートクラスを実際に動かせるようにしましょう。メンバ関数のReadとWriteは宣言だけしかしていないので、このままでは動きません。それには下に示すように中身を定義してやらなければいけません。

List 2.2 ノートクラスのメンバ関数の定義

// ノートを読む.
// 仮引数の型がvoidのときはそれを省略できる.
string Notebook::Read() const
{
    return note;  // noteの内容を返す.
}

// ノートに書く.
void Notebook::Write(string str)
{
    note = str;   // noteに代入する.
}

メンバ関数を定義するときは、どのクラスの関数であるかを示すためにスコープ解決演算子(::)を使ってstring Notebook::Read() constのようにするわけです。あとは普通の関数を作る要領でOKです。どうですか。とっても簡単でしょう(^-^)。

それでは実際に、このプログラムがどのように動作するのか見てみましょう。

List 2.3 ノートクラス全体

#include <iostream>
#include <string>
using namespace std;

// ノートクラス.
class Notebook {
private:
    string note;  // ノートの本文.

public:
    string Read(void) const;  // ノートを読む.
    void Write(string);       // ノートに書く.
};

// ノートを読む.
string Notebook::Read() const
{
    return note;  // noteの内容を返す.
}

// ノートに書く.
void Notebook::Write(string str)
{
    note = str;   // noteに代入する.
}

int main()
{
    Notebook notebook;  // ノートクラスのインスタンス.

    notebook.Write("This is a notebook.");  // ノートに書き込んで.
    cout << notebook.Read() << endl;        // それを読む.

    notebook.Write("This notebook is good.");
    cout << notebook.Read() << endl;

    return 0;
}


This is a notebook.
This notebook is good.

うまく動いたようですね。ところで、main関数の中でノートクラスのインスタンスという部分がありますよね。これはクラスの実体を定義しています。つまり、Notebookというクラスを用いて作る中身です。ここではその実体をnotebookとしましたが、日記を付けたいのならNotebook diary;とできますし、はたまた黒板にしたければNotebook blackboard;とすればよいのです。そして、それぞれdiary.Write("Today's episode.");とかblackboard.Read();のように使うことができます。

メンバ変数やメンバ関数を使用するには、.を用いて、notebook.Read()のように使用します。もし、notebookがポインタで宣言されていれば、->を使用して、notebook->Read()のようにします。

これでとりあえずは、クラスの基本がわかったことと思います。次からはこのクラスを用いてどのようなことができるかを調べていくことにしましょう。


← 前に戻る | 次に進む →


Copyright (C) Noriyuki Futatsugi/Foota Software, Japan.
All rights reserved.
d2VibWFzdGVyQGZ1dGF0c3VnaS5uZXQ=