質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.32%

C言語でオブジェクト指向プログラミングはどれくらいされている?

解決済

回答 8

投稿

  • 評価
  • クリップ 6
  • VIEW 6,368

otaks

score 218

C言語でオブジェクト指向プログラミングは何とかできそうなところまでは分かったのですが、実際どれくらい使われているのでしょうか?
経験から等教えて下さい。

自分の第一感では、ソースとモジュールに分けて、カプセル化・継承ぐらいはやるかもだけど、多態性はコードが複雑になりすぎるのでやらないかな、という感じです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 8

checkベストアンサー

+4

C言語プログラムへのオブジェクト指向(設計)適用は、程度の差こそあれ、それなりに行われていると思います。書籍「モダンC言語プログラミング」でも紹介されていますね。

この手の議論では、オブジェクト指向(設計)のような 方法論 と、プログラミング言語が提供する 機能 は分けて考えた方が良いです。既に多数指摘されるように、C言語の言語機能それ自身は、ほとんどオブジェクト指向をサポートしません。C言語で記述するプログラムにオブジェクト指向の考え方(設計)を適用することは可能ですが、言語側サポートが無いため本質的でない煩雑なコードを必要としたり、その設計思想を理解していない将来のメンテナンスによってルールが破られるリスクが高まります。

自分の第一感では、ソースとモジュールに分けて、カプセル化・継承ぐらいはやるかもだけど、多態性はコードが複雑になりすぎるのでやらないかな、という感じです。

仰る通り、C言語でも不透明型(opaque type)によるモジュール化・カプセル化は比較的容易に適用できます。標準ライブラリのFILE*型+fopen等の操作関数もこの一種ですね。

継承(inheritance)も、単に構造体(struct)を入れ子にしてキャスト利用するくらいならたまに見かけますが、仮想関数/動的束縛のような多態性(polymorphism)の実現あたりからC言語では実装が辛くなってきます。それでも、後者はFFmpegライブラリで使われています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

あんまりやってないんじゃないスかねえ。
C言語で無理やりオブジェクト指向もどきを実現さすくらいなら
オブジェクト指向に適した言語や環境を選択するのが吉かも。

プログラムの保守性などは重要なポイントだと思うのですが、
おっしゃるようにオブジェクト指向のメリットを優先させる
ほどの優位性はそんなにない気がします。
あくまでオブジェクト指向の考え方にならえる部分は
ならっておく。と、自分なら考えます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

こんにちは。

以前、Linuxのカーネルを読んだ時、オブジェクト指向的なプログラムされているなと思ったことが有ります。
データと関数ポインタをセットにしているイメージですね。(仮想関数的なテクニックだったように思います。)
正直、その部分はむちゃくちゃ読みにくいと感じました。(注)
そのポインタに何が設定されているのか追いかけるのがたいへんすぎ。

オブジェクト指向的な記述を多用するのであれば、普通にオブジェクト指向言語を使った方がメンテナンス性は良いと思います。

実際どれくらい使われているのでしょうか? 

C++を使えない環境でオブジェクト指向テクニックを使うと何かメリットがある時には必要な部分のみ使われる程度ではないでしょうか?


(注)
でも、誤解のないように補足。Linuxは良いOSと思いますよ。
構造がシンプルなので読みやすいです。ムダに複雑ではないのですよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/13 09:13

    iwamoto_takaakiさん。

    あはは、なるほど。リーナス氏がC++を嫌いという話は聞いてましたが、ここまでとは。

    OSのカーネルを書くときは処理系に任せないで全部自分でコントロールしたいってことだろうと思います。
    平均的なプログラマがC++を使って細かい部分を処理系任せにしないプログラムを書くのはかなり厳しいですが、Cなら平均的なプログラマでも細かい部分を制御できますから。
    逆に言うと、Cの場合は細かい部分に常に注意を払わないといけないので生産性が上がらないってことでもあるのですけどね。

    望ましくは、C++に熟練して性能と生産性のトレードオフを高いレベルで満たせるプログラマを目指したいものです。

    キャンセル

  • 2016/06/13 22:18

    OSのカーネルばっかり書いている人になると、別次元なんでしょうね。

    キャンセル

  • 2016/06/14 21:22

    完全に雑談になってしまうかもしれませんが、linuxのdevice-mapperはデザインパターンで言うところのデコレータ/コンポジットパターンをアーキテクチャレベルで実現していますね。ある言語内(シンタックスレベル)で閉じたデザインパターンでなく、アーキテクチャレベルでそれをやっていてスゲーというか、関心したことがあります。それを言うならVFSだってそうなんですけども。

    うまく表現できませんが、コンパイル時に解消される抽象度ばかりに関心がいっていたので、コンパイルした後にも抽象度を保つ(言語に依存しない)設計や考え方があるんだ、みたいなことをそのとき思いました。デザインパターンは言語に依存しない、というのはこういう意味も含んでいたのか?、と。

    リーナス氏がコンパイル時に解消される抽象度(C++のフィーチャー)には興味が無さそうにみえるのは、さらに上の設計レベルの抽象度のことを考えてるからかもしれません(完全に個人的な憶測)。

    キャンセル

+2

他のコメントを読んでの感想ですが、技術的要因でC++など他のオブジェクト指向言語が選択できない環境ではともかく、政治的理由から「C言語によるオブジェクト指向」を選択するのはまったくおすすめできません

というのも、C言語でやろうとすれば、

  • コードの記述としてはオブジェクト指向の言語でやるよりはるかに冗長になる
  • 考え方が変わるコードである以上、勝手に入れるわけにも行かない
  • 勝手にやりだしたら、当然「自分以外には理解できない」コードという、チーム開発で作ってはならないものになってしまう
  • C言語である以上、保護機構は存在しないので、簡単に「横紙破り」できてしまう

ということで、(勝手にやりだすというパターンを除けば)まだC++を導入するよう説得するほうがいいのではないかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/12 12:04

    ちなみに、「GObject」という、C言語でオブジェクト指向を実現するためのライブラリも存在はしています。

    キャンセル

  • 2016/06/12 13:11

    カプセル化・継承・多態性すべてをCで導入したいとは思っていません。
    多態性をCでやろうとすると複雑になります。
    だだし、カプセル化に限れば、モジュールにソースを分けた後
    ・構造体の不完全宣言
    ・構造体定義を.cに定義
    のルールさえ守れば、そのメリットを享受できます。

    また、継承についても
    ・構造体の一番上にサブクラスを定義
    ・ヘッダを公開用、サブクラス用に分ける
    ぐらいで、そのメリットを享受できます。

    これらのルールの徹底、適用後ソースの保守性(*1)コストは
    メリットより高くつかないと個人的には思います。

    (*1)マクロな視点では名詞的な単位で管理できるようになる分向上する部分もあると想定

    キャンセル

  • 2016/06/13 21:11

    いちおう確認ですが、導入形態としては「自分だけがやっているものに投入/チーム内で合意を図った上で投入/自分の書く部分から徐々に導入」などが考えられますが、どのようなかんじでしょうか。

    キャンセル

+1

かつて仕事でそのようなコードをメンテナンスしたことがあります。構造体のメンバ変数に関数ポインタを並べてクラスっぽくしていましたが、ポインタはポインタでしかないので、実際にどの関数が呼ばれるかは、「ソースを全検索」してメンバ変数を設定している部分を探さないと判りません。IDEの支援は受けられません。関数ポインタへの設定を間違えてバグを引き起こしていた箇所もありました。

C言語でもオブジェクト指向プログラミングの「真似事」はできるでしょうけど、言語が想定していないことを無理矢理やろうとすると、手間がかかったり可読性が下がったりデバッグが困難になったり、あるいは無用なバグを誘発する危険もあり、かえって生産性を下げることになります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

少なくとも私は使ってないし、周りで使っているのを見たこともないです。

確かC++の一番最初はC言語のプリプロセッサとして実装が始まったはずです。なので、そういうプリプロセッサを準備できれば、と、ふと思いましたが、既に最新のC++コンパイラがあるのにそれをやるメリットが思い浮かびません。

C言語で無理くりやったとしてもオブジェクト指向のメリットを享受できないばかりか、却って生産性を悪くしてしまうと思います。そんな苦労してやるくらいなら、C言語として素直にプログラムしたほうがよっぽど良いと私は思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

OOPの為にC++を作ったのに、何故にCで行う必要があるのでしょう?
今や、マイコンの処理系としても、C++は実装されたりしています。
⇒実用的に使うには、それなりのメモリが必要なので、
遊びのマイコン用途では、C++はあえて使いません。
どうかすると、Cすら除外して、アセンブラ使用を考えたりします。

考え方や、プログラミングの方便としては使い処は有ると思いますが、
車輪の再発明という点で、意味があるのでしょうか?

takasima20 さんが書かれている様に、OOPが実現できる、処理系、環境を、用途によって
選ぶ方が現実的ではないでしょうか。

私的には、MSが .NetMicro Framework と、Senser API の普及への熱意が感じられない、
Windows IOT 系が、中途半端になりそうで、様子見。
⇒何でも良いから、垂直統合が可能な環境、処理系をどうかして欲しい。
Linux / Windows / RTOS / Framework バラバラで、学習コストがかかり過ぎ。
TRONプロジェクトに有った兆しを受け継いでいる物がないかなぁ。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/12 16:59

    横から失礼します。

    > ・既存エンジニアがC++を使いこなすまで非常に時間がかかる

    これはつまり、既存エンジニアたちはオブジェクト指向を理解していないということでしょうか。であるなら、そもそも、C言語でオブジェクト指向プログラミングをさせるのは無理だと思います。おそらく混乱するだけでしょう。
    どうしてもオブジェクト思考プログラミングを導入したいのなら、まずは既存エンジニアたちにC++(オブジェクト指向)の学習機会を与えるべきです。その後で徐々にC++に移行するのが一番の近道だと思います。

    キャンセル

  • 2016/06/12 17:21

    理想論ではありますね。それができるのであればやりたいです。
    そもそもデザインパターンだの言ったところで、ずっとCでやってきた人が
    いきなりできるようになるとは思えないです。少しずつでもいいから、
    一部をオブジェクト化して、肌感覚でそれを感じることが大切だと思います。
    泥臭くてもいい現実的な解を模索しています。

    キャンセル

  • 2016/06/12 18:17

    理想論ではなく現実的なことを書いたつもりですが……。
    Cのソースはそのまま拡張子を変えてC++としてコンパイルできますし、修正が必要だとしてもさほど難しいものではありません。CとC++は相互接続が容易なので、できるところから徐々にC++に移行し、オブジェクト指向プログラミングを導入していく方法がとれます。現に私はそうしてきました。C++=デザインパターンではありません。

    とはいえ、ここまでC言語にこだわるのはいろいろ事情があってのことでしょう。やってみて考えるというのもありだと思います。

    キャンセル

-3

記憶違いかもしれないですが、
printf、sprintf、fprintf等は、vprintfという関数に集約されていたと思います。
( printfからvprintfを呼んでいるし、sprintfからもvprintfを呼んでいる。 )

考え方としては「多態性」になるかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/14 18:40

    実装重複を避けるためにprintf系関数の内部実装としてvprintf関数が利用されることはありますが、それをオブジェクト指向的な「多態性」とは呼ぶことはありません。

    キャンセル

  • 2016/06/14 23:41

    yohhoy さんコメントありがとうございます。
    「多態性」を良く理解できていなかったようです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る