プログラミング教室


■C++言語を勉強する前に知っておきたいこと

プログラミング言語は、
    プログラムする人が、不便を感じたので
        「便利になるように」進化してきた。

これを聞くと「当たり前じゃないか」と思ったでしょ。
でも、C++を理解する近道は、「便利になるための方法を学ぶことだ」と私は後から痛感したのです。

系統立てて、文法を解説してある本ばかりだけど、理屈じゃなく実は「実利」が最も重要だった。
実際はプログラマーが不便だから、新しい概念が組み込まれているんです。
だから本を読んだ時「いつ使うのか」が全くイメージできないから、頭に入らないんです。

少しだけ、プログラミング言語の歴史を振り返ります。

昔は、グローバル変数だけしか使えず、Goto しか無かった。
Gotoを線で追うと、スパゲッティのようになってしまったので、スパゲッティプログラムと呼ばれた。
Goto使いまくりで、本当に追うのが大変だったんです。そこで、サブルーチンが発明されました。

同じ処理を書かなくてもよくなったけど、少し違う処理を書くときに、サブルーチンをコピーして書いてしまう。
後で、片方のサブルーチンに都合がいいようにグローバル変数の値を変更したりすると、コピーしたサブルーチンは動かない
なんてことが良く起こる訳です。
そこで、サブルーチン内だけで使える(ローカルな)変数と引数が発明されるんです。←C言語発明(1972年)

1978年 The C Programing Language 初版発行ですが、日本語訳は 1981年です。
C言語ではサブルーチンが値を返すことができるようになったので、関数と呼ぶようになります。

この発明のお陰で、サブルーチンを分離(グローバル変数に影響が無い)して管理できるようになった。
「このサブルーチン群は再利用できるライブラリにできるね」とグループ分けして、モジュール化へと進む訳です。
モジュール化すると、複数の画面からコールされると、モジュール内で変数が被ってしまい。上書きされる問題とかが発生します。
そこで、モジュールでは無く、コールした単位で変数の管理も行う必要があると分かってくるんですね。

ここで、オブジェクト指向という概念を導入した沢山のプログラミング言語が生まれます。
世界的に普及していたC言語を拡張した、C++言語も発明されます。

1983年 C with classes が発表されます。

新しい概念が導入され、沢山の便利機能が拡張されました。
便利機能を「実利に着目して」列記します。

クラス
  オブジェクトを生成する時に元となる宣言です。変数も関数も別管理できる拡張版モジュールです。
  生成すると変数領域が別管理され、意図せぬ変数の上書きの心配無いものを利用できます。
  変数も関数さえも宣言のみですから、呼び出したり使えません。
  オブジェクトを生成して初めて使えるようになります。

継承
  クラスを親と見立てて、派生させた子クラスを作成する時の呼び方です。

  class 子クラス : public 親クラス
  {
  public:
    ;
  private:
    ;
  };
  
  親子と見立てるので変な説明が必要になるのですが、「楽したいので、このクラスの機能を使います」と思えばいいです。
  子クラスは親クラスを自由に使って、「追加プログラムだけを書いて拡張できる」んです。
  この時に制限をかける方法が、public や private です。
  
オーバーライド(上書き)
  親クラスで宣言してある関数と同じ名前の関数を子クラスでも宣言する時にオーバーライドすると言います。
  ちょっと拡張したいんだけど、ウインドウを閉じるときに、closeWindowと名前をつけたいじゃないですか
  呼び出し側もスッキリしますしね。同じ名前を使えるメリットは、後で分かってきますが、親クラスを変更しても
  名前が同じなら、親クラスを別の親クラスにすり替えるだけで済むんですよ。
  これは後から仕様が変更になった時にも超便利なのがわかりますよね。
  上書きするけど、関数の名前だけで、元の関数は残っています。子クラスからも呼べば呼び出せます。
  呼び出さない時は、完全に新しい(上書きされた)関数のように見えます。

仮想関数
  継承した子クラスでオーバーライドされる事を想定した関数。
  virtual と宣言を付けておくと、予定外の使い方をしたら、コンパイルエラーにしたり出来る機能です。
  また、virtual を付けていないと、同じ名前の新しい関数は呼び出されないのです。
  必ず、オーバーライドしないとエラーにすることもできます。(純粋仮想関数)

多重定義(オーバーロード)
  似た機能だが名前が違う関数が沢山必要となるのを解決してくれる機能です。

    Data_from_Int(int a)
    Data_from_short(short a)
    Data_from_long(long a)
    Data_from_double(double a)

  DataFromNum などの関数名で統一できると便利ですよね。
    DataFromNum(int a)
    DataFromNum(short a)
    DataFromNum(long a)
    DataFromNum(double a)
  と定義していると、

  obj.DataFromNum(a);と書いた時、コンパイラには a の型が分かっているので、コンパイラが判断してくれる。
  プログラマーからすれば、スッキリした表記になります。
  こんなことがクラスの設計時に設計できる機能です。
  演算子のオーバーロードができれば、クラスを使う人が楽にコーディングできるようになるから必要になるのです。

C++言語の新しい概念の見方が変わりませんか?
私はこれを先に知っていたかったと思いました。
今説明したレベルを理解できれば、後は使いながら理解を深めていけます。


プログラミング教室 一覧へ