【C言語】完全なオブジェクト指向ではなく、Interfaceのみを利用する選択【Golangを参考に】

C言語とオブジェクト指向は相性悪い

オブジェクト指向は、C言語でも実現できます。

C言語は、言語によるオブジェクト指向プログラミングのサポートがありません。しかし、開発者が注意深く実装する事によって、オブジェクト指向プログラミングが可能です。

詳しくない方は、「C言語によるオブジェクト指向プログラミング入門」や「モダンC言語プログラミング」を手に取るか、GLib(GNOME ToolKitのベースライブラリ)のようにオブジェクト指向プログラミングで実装されたコードを確認してみてください。

C言語にオブジェクト指向を適用する場合、実装規模が爆発的に増えます。さらに、プロジェクトに旗振り役のリーダーが居ないと、容易にオブジェクト指向が崩れます(言語がオブジェクト指向を強制しないため)。

そもそも、C言語プログラマも他言語プログラマも、C言語とオブジェクト指向の組み合わせには拒否反応を示す可能性が高いです。C言語プログラマ視点では「労力の割にリターンが少ない」と感じ、他言語プログラマ視点は「クラスを作るためだけに、どれだけコードを書かせるのか」と感じます。

      

オブジェクト指向のメリットを得るために、C++やVala言語を選択する方法もあります。しかし、プロジェクトによってはC言語を選択しなければならない場合があるでしょう(補足:Vala言語はC#のような文法を持ち、valaファイル → C言語ファイル(中間ファイル) → バイナリの順でコンパイルするマイナー言語)

Introducing Vala Programming(Michael Lauer著、35頁)より引用

Introducing Vala Programming(Michael Lauer著、35頁)より引用

             

上記のような課題を踏まえて、C言語ではどこまでオブジェクト指向ライクに実装すべきでしょうか。その現実解は、「Golangのようにクラス構造や継承を捨て、Interfaceだけ利用する」ではないかと感じ始めました。

              

C言語とInterfaceの組み合わせは簡単

C言語とオブジェクト指向との組み合わせで面倒な部分は、「クラス構造(new, deleteサポート)」、「継承の実現」、「public、protected、private等のアクセス範囲コントロール」です。

面倒な割に、メリットがほぼ無いです。現代のプログラミングでは、「継承を使わない方が良い」という見解が強まっています。継承がなければ、クラス構造とprotectedの利点が薄れます。つまり、苦労して実装したオブジェクト指向の使いどころが殆どありません。

 

その一方でInterfaceはどうでしょうか。

C言語では、Interfaceは関数ポインタをメンバ変数に持つ構造体です。新しい構造体(Interface)を一つ作り、Interfaceを別の構造体(データを持つメンバ変数)に含める方法は、とても簡単に実現できます。

Interfaceの利便性は、様々なコードで証明されています。例えば、Linux Kernelではファイル操作のInterfaceがfile_operations構造体として定義されています。

 

file_operations構造体(Interface)に対して、操作するファイル種類ごとに異なる関数ポインタをセットすれば、処理を柔軟に切り替えられます。

下手にガチガチのオブジェクト指向をC言語に適用するよりは、Interfaceの適用ぐらいが費用対効果的に好ましいのではないかな、と考えています。

               

後書き:C言語から離れるので最後にポエム記事

転職した関係で、大学時代から10年近く触り続けていたC言語とお別れします。そのため、最後にポエム記事を書きました。

C言語はプログラマのスキルが如実に反映される言語であり、OSSのコード(Linux Kernelやsystemd等)を見ると、そのレベルの高さ(作者の頭の良さ)を痛感する事が多かったです。システムプログラミングや組み込みには、C言語は良い言語です。ただし、趣味のコーディングではもう選択しないと思います(GolangやRustを選択するかな)。

今振り返れば、私が大学生/大学院の頃(2009〜2014年)は、世間様も私自身もオブジェクト指向信仰が強かった気がします。私は、オブジェクト指向こそが設計の全てのように錯覚していました。しかし、最近(2021年)は関数型言語の良さがJava等の言語に取り込まれたり、クラス構造をそこまで大事にしないGolangが流行っています。staticおじさんの時代とは変わったな、と思わずにはいられません。

私の中でもオブジェクト指向への憧れや固定観念は、薄れてきました。以前よりフラットな視点で「C言語とオブジェクト指向の関わり方」を再考した結果、「Interfaceがあれば良いのでは?」と考えた次第です。

             

おすすめ

1件の返信

  1. 2021年11月23日

    […] 別記事でも書きましたが、C言語でOOPを利用した例はLinux KernelやGNOME Toolkit Libraryと数多くあります。しかし、OOPを導入するハードルの高さの割には、恩恵が少ない欠点があります。C言語の代わりにC++、Golang、Rustでコーディングした方が早いのではないかと感じる事も多いです。 […]