ショートカット
ファシリテーター × あり方
コーディングの向こう側
Hello, ANOTHER world!
オブジェクト指向のはなし
プログラミングのはなし
C言語実力診断クイズ
eSkillBooks
オブジェクト指向のはなし

カプセル化と情報隠蔽の記述

導入

オブジェクト指向では、クラスのユーザーがどのメンバにアクセス可能か指定することによって情報隠蔽を実現します。インターフェイスと実装を完全に分離するにはインライン関数を使います。

用語
このトピックでは次の用語を覚えます:
  • public/private キーワード
  • インライン関数
解説

C++ では、クラス宣言で記述されたメンバ関数は、そのクラスと、それを継承したサブクラスに対してのみ使用できます。逆に、次に述べるような方法を用いてアクセスを制限すれば、クラスの属性を直接操作できる関数をメンバ関数だけにすることができます。これによって、カプセル化が実現できます。

C++ では、クラス宣言のときに public/private キーワードを使って各メンバへのアクセスを制限します。次のコードは前のトピックと同じものですが、public/private キーワードが使用されています。

SAMPLE CODE
クラス宣言ファイル(ファイル名:"test.h")

#ifndef INCLUDED_test
#define INCLUDED_test


// class 宣言
class Human {
public:
    // コンストラクタ
    Human( const char *pcName, int nAge=0 );
    
    // デストラクタ
    virtual ~Human();
    
    // 属性の取得:「名前」
    const char *Name() { return m_pcName; }
    
    // 属性の取得:「年齢」
    int Age() { return m_nAge; }
    
    // メソッド:「年をとる」
    void IncreaseAge();

private:
    // メンバ変数:「名前」
    const char *m_pcName;
    
    // メンバ変数:「年齢」
    int m_nAge;
};

#endif // #ifndef INCLUDED_test

public キーワードは、それ以降のメンバがクラスの外部からアクセス可能であることを意味します。したがって、Human, ~Human, Name, Age, IncreaseAge はクラス Human の利用者にとって使用可能です。これはすなわち、これらがクラス Human のインターフェイスであるということです。

private キーワードは、それ以降のメンバがクラスの外部からアクセス不能であることを意味します。つまり、そのクラスのメンバ関数のみが private メンバにアクセスできるようになります。上の例では、m_pcName, m_nAge はそれぞれ属性の実装であるため、クラスの利用者にアクセスされないようにしているのです。

このように、C++ ではクラスの利用者がどのメンバにアクセス可能であるかを指定することによって、カプセル化を実現します。もちろん m_pcName, m_nAge を public として直接アクセスさせるようにし、Name, Age メソッドを省略することもできます。しかしそのような方法は得策ではありません。あとで属性の実装を変更したくなった場合の修正が困難になるためです(カプセル化が情報隠蔽の一種であるということを思い出してください!)。

また、m_pcName, m_nAge を public として直接アクセスさせるようにした方が実行速度が増すと思われるかもしれませんが、そうではありません。上の例では

const char *Name() { return m_pcName; }

のようにしてクラス宣言の中にメソッドの定義を挿入していますね。このような関数をインライン関数と呼びます。インライン関数は関数のように記述されますが、実際には関数呼び出しを行うかわりに関数の定義内容をそのまま呼び出し元に埋め込みます。つまり、インライン展開されます。そのため関数呼び出しのオーバーヘッドがかからず、実行速度の低下がありません。

もっと!
もっと詳しく知りたい人は次の用語について調べると良いでしょう:
  • friend
  • inline
  • protected

(「オブジェクト指向のはなし」は1999年2月から2000年4月にかけて作成されたコンテンツです。)