こんにちは、ナナです。
ここまで「ファイルハンドル」の使い方を学んできました。この「ハンドル」の仕組みを理解することは、次の技術へのステップアップに向けて重要な意味を持ちます。
プログラミングの勉強をしていると「オブジェクト指向」という言葉を耳にすることがあるでしょう。
昨今のプログラミング言語は、この「オブジェクト指向」というものが主流であり、そういった言語を「オブジェクト指向言語」と呼びます。
本記事では、C言語とハンドルの関係性から「オブジェクト指向」の概念を理解することが目的です。
C言語で学ぶ「オブジェクト指向」
最近みんなが口をそろえて「オブジェクト指向」と言っているわ。わたくしもそのブームに乗るわよっ!
「オブジェクト指向」というものを、わかりやすくお教えなさい!
C言語を学んだ次のステップとして「オブジェクト指向言語」を学ぶことは悪くないよ。
「オブジェクト」というものの考え方を知ることが大事だよ。
オブジェクト指向言語の種類
オブジェクト指向言語で、代表的な言語は次のものです。
この中に「C言語」は含まれていませんね。
そうです。「C言語」はオブジェクト指向言語ではありません。
「オブジェクト指向」をプログラミング未経験者が学ぶのは難易度が高いと言えます。C言語でプログラミングの基礎を学んだ後の、次の言語として「オブジェクト指向言語」を学ぶのは良い選択でしょう。
オブジェクト指向を学ぶ価値
「オブジェクト指向」という仕組みや考え方は、学ぶ価値は十分にあります。
最近の言語でこれほど「オブジェクト指向」がサポートされているということは、プログラムを構築する上でメリットがあるからです。
それでは、オブジェクト指向言語ではない「C言語」において、「オブジェクト指向」という概念は学ぶことはできるのでしょうか?
答えは
YES
です。
C言語は確かに「オブジェクト指向言語」ではありません。しかし、疑似的なオブジェクト指向を実現し体験することは可能です。
本記事を学ぶ前に「ファイルハンドル」について学びました。それは、この「疑似的なオブジェクト指向」を理解するための伏線なんですよ。
本格的なオブジェクト指向を学ぶ前に、少しだけオブジェクト指向の雰囲気を感じておきましょう。
プログラム世界の「オブジェクト」の捉え方
C言語はオブジェクト指向じゃないのね。それでも「オブジェクト」って何なのかを、あなたは説明できるのかしらっ!
結局、「オブジェクト」って何なのよっ!
プログラムを学び始めたばかりの人は「オブジェクト指向」という考え方は、なかなか最初はしっくりこないかもしれない。
それでも、プログラムという世界における「オブジェクト」というものの捉え方を、少しイメージできるようになるのが最初の一歩だよ。
「オブジェクト指向」という考え方は、プログラミングを学び始めたばかりの方には少し難しいものであることは否めません。
しかし、本サイトをここまで進めてきた方は、その一歩を踏み出す時期に来ているのは確かです。
オブジェクトとは「モノ」であり「部品」である
皆さんの身の回りにある製品は、様々な「部品」から構成されています。
例えば、車は「エンジン」「タイヤ」「ハンドル」「シート」「ライト」・・・といった様々な部品が、結合し大きなひとつの「車」として作り上げられています。
ソフトウェアのシステムもこの考え方と同じように、部品を組み合わせることで作りやすくメンテナンスしやすいプログラムができます。
それがプログラミング世界における「オブジェクト」のイメージなのです。
英語の「オブジェクト」とは「モノ」を示す言葉です。プログラムを「モノ」という感覚で捉えることが、オブジェクト指向を理解するコツです。
C言語プログラムにおける「オブジェクト」とは「ハンドル」
皆さんは、ここまでC言語を学んできましたが、「変数」と「関数」というものを中心にプログラムを作成してきましたね。
C言語に限らず、大まかにプログラムというものを捉えると、この2つの要素で構成されています。
C++やJavaといった言語は、言語仕様として「オブジェクト」という機能をサポートしています。
オブジェクト指向言語においては、「データ」「処理」をまとめてグループ化できる機能を言語的にサポートしています。
それが
「クラス」
と呼ばれるものです。
「クラス」は、C言語における「構造体」のような型の枠組みを提供します。そして、「クラス」という型からメモリ上に生成された変数を「オブジェクト」と呼びます。
しかし、C言語は「オブジェクト指向言語」ではないため、言語仕様として「オブジェクト」というものは存在しません。
そんなC言語で、「オブジェクト」の代わりとなるのが
「ハンドル」
です。
「ハンドル」とは、オブジェクト指向ではない「C言語」の世界において、疑似的に「オブジェクト指向」を実現するための仕組みなんです。
「ハンドル」の概念を正しく理解しておくと、「オブジェクト指向言語」の学習において理解がスムーズになります。
本格的なオブジェクト指向の全ては学べませんが、今のうちに「オブジェクト」というものの捉え方を経験しておくのです。
「ファイルハンドル」から知る疑似的なオブジェクト指向
「ハンドル」が「オブジェクト」なのっ!どういうこと?
「ファイルハンドル」を学んだわたくしは、すでにオブジェクト指向をマスターしているってことなの?
現時点で「ファイルハンドル」を使ったから「オブジェクト指向」をマスターしているとは思わないでね。でも、「ハンドル」という仕組みを理解すれば、その一歩を踏み出したと言えるね。
皆さんはここまで、「ファイルハンドル」というものを使ってファイルを制御してきました。
この「ハンドル」の仕組みは、「オブジェクト指向」の考え方と酷似しています。
それでは「ハンドル」を改めて深堀りしていきましょう。
「ファイルハンドル」は「ハンドル」のひとつでしかない!
「ファイルハンドル」は、C言語を学ぶ項目としてよく登場します。
しかし、本サイトで皆さんに本当に学んで頂きたいことは、「ファイルハンドル」の扱い方ではありません。
それは
「ハンドル」の仕組みを知ることで「オブジェクト指向」の概念を手に入れること
です。
ファイルハンドルというのは、「ハンドル」という概念を具現化したひとつの姿でしかないのです。
皆さんが学ぶべきなのは「ファイルハンドルの使い方を学んだ」ではなく、「ファイルハンドルからハンドルの概念を学んだ」なのです。
「ハンドル」という世界を、もっと広い視野で捉えましょう。「ハンドル」というものを皆さん自身の手で構築することだってできるのです。
ファイルハンドルから知る「ハンドル」の構成要素
ハンドルの基本構成が、この「生成」「制御」「解放」の3つです。
「ファイルハンドル」では、ハンドルを扱うための様々な標準ライブラリ関数が登場しました。各基本構成要素には次の関数が紐づくことになります。
構成要素 | 関数名 |
---|---|
ファイルハンドルの生成 | fopen、fopen_s |
ファイルハンドルの制御 | fgetc、fputc、fgets、fputs、fscanf、fprintfなど |
ファイルハンドルの解放 | fclose |
組み込み開発の世界では「ファイルハンドル」を利用できる環境はそれほど多くありません。
しかし、「ハンドル」という仕組みを使って、独自の情報を管理するケースは私の経験上、比較的多いのです。
ハンドル生成の役割
ハンドル生成で行うことは、ハンドルとして管理するデータをメモリ上に確保し初期化することです。
ここで使用するメモリは、malloc関数による動的メモリが基本となります。開発環境によってmalloc関数が利用できない場合は、静的メモリを使ってハンドルを管理します。
ハンドルメモリ領域 | 割り付け方 |
---|---|
動的メモリ | 生成要求時にmalloc関数によりメモリを割り付ける。 ポインタでハンドルを管理するのが一般的である。 |
静的メモリ | あらかじめハンドルの最大同時利用数を決定し、ハンドル領域を事前確保しておく。 生成時には、対象ハンドルのポインタやインデックス番号を提供する。 |
スタックメモリ | ハンドルとして利用はできない。 |
関数から抜けてしまうと消滅するスタックメモリはハンドルには使えません。
ハンドル制御の役割
生成されたハンドルを利用して、サービスを要求するのがハンドル制御の役割です。
制御に関する処理は、どのようなハンドルを作り出すかによって大きく変化します。例えばファイルハンドルの場合は、次のようなものになります。
ファイルハンドルの制御 | 役割 |
---|---|
fgetc | ファイルからの1文字読み取り |
fgets | ファイルからの文字列読み取り |
fputc | ファイルへの1文字書き込み |
fputs | ファイルへの文字列書き込み |
ハンドルを自前で作成する場合は、ハンドルに対する要求としてどのようなものがあるのかを考えられる力が必要となります。
これはハンドルの利用者側の視点に立って、「どのような制御が求められるだろうか?」を考えることなのです。
ハンドルを自作する場合は、この制御部分をいかに利用者にとって便利な姿で設計できるかが腕の見せ所になります。
ハンドル解放の役割
生成されたハンドルを破棄するため役割です。確保されたメモリの種類により行うことが変わります。
ハンドルメモリ領域 | 解放処理の内容 |
---|---|
動的メモリ | free関数により動的メモリを解放する。 |
静的メモリ | 対象ハンドル領域を無効状態として初期化する。 |
ハンドルとは利用したい時に生成し、不要になったら破棄できる構造にしておきます。
このようにすることで、プログラムが動いている最中に様々な利用者がハンドルを活用できるようにします。
この内容を理解できれば、オブジェクト指向の「クラス」と「カプセル化」を理解する最低限の知識を手に入れたことになります。