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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

8回答

8208閲覧

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

otaks

総合スコア223

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

4グッド

6クリップ

投稿2016/06/11 23:34

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

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

mpyw, stereo_code, ai_2013_dev, h_ohsw👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答8

0

ベストアンサー

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

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

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

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

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

投稿2016/06/13 06:35

yohhoy

総合スコア6189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

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

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

投稿2016/06/12 03:02

maisumakun

総合スコア145123

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2016/06/12 03:04

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

2016/06/12 04:11

カプセル化・継承・多態性すべてをCで導入したいとは思っていません。 多態性をCでやろうとすると複雑になります。 だだし、カプセル化に限れば、モジュールにソースを分けた後 ・構造体の不完全宣言 ・構造体定義を.cに定義 のルールさえ守れば、そのメリットを享受できます。 また、継承についても ・構造体の一番上にサブクラスを定義 ・ヘッダを公開用、サブクラス用に分ける ぐらいで、そのメリットを享受できます。 これらのルールの徹底、適用後ソースの保守性(*1)コストは メリットより高くつかないと個人的には思います。 (*1)マクロな視点では名詞的な単位で管理できるようになる分向上する部分もあると想定
maisumakun

2016/06/13 12:11

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

0

こんにちは。

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

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

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

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


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

投稿2016/06/12 00:44

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MIURA_Yasuyuki

2016/06/12 02:27

Linuxくらい大きな規模になるとメンテナンス性( コードの読みやすさ、変更のしやすさ、他 )のためにコードを作っていく結果、オブジェクト指向的になる部分があるのかと思いました。意図的にオブジェクト指向的というより、良い構造を探っていった結果、オブジェクト指向的になったのではないかと。 Linuxのカーネルは書籍等で少し読んだ事がある程度です。的外れなコメントでしたらすいません。
Chironian

2016/06/12 03:01

MIURA_Yasuyukiさん。コメントありがとうございます。 > 意図的にオブジェクト指向的というより、良い構造を探っていった結果、オブジェクト指向的になったのではないかと。 私もそう思いますよ。 C++があるのに意味もなくC言語でオブジェクト指向的な記述をしたプロジェクトが成功するとは思えません。つまり、LinuxはC言語でオブジェクト指向的記述を行う意味(メリット)があったのだと理解しています。
otaks

2016/06/12 08:15

Cでもオブジェクト指向をしていた人たちがいた。言語作成者がそれをみて言語にオブジェクト指向の構文を取り入れたのだとどこかで見たような見なかったような
iwamoto_takaaki

2016/06/12 14:59

リーナスがC++について言及しているのを思い出したので、紹介させて下さい。 http://tabesugi.net/memo/2009/1a.html#152154 オブジェクト指向がそこまで悪いとは思えませんが、ちょっとニヤリとしまう話です・・・
Chironian

2016/06/13 00:13

iwamoto_takaakiさん。 あはは、なるほど。リーナス氏がC++を嫌いという話は聞いてましたが、ここまでとは。 OSのカーネルを書くときは処理系に任せないで全部自分でコントロールしたいってことだろうと思います。 平均的なプログラマがC++を使って細かい部分を処理系任せにしないプログラムを書くのはかなり厳しいですが、Cなら平均的なプログラマでも細かい部分を制御できますから。 逆に言うと、Cの場合は細かい部分に常に注意を払わないといけないので生産性が上がらないってことでもあるのですけどね。 望ましくは、C++に熟練して性能と生産性のトレードオフを高いレベルで満たせるプログラマを目指したいものです。
iwamoto_takaaki

2016/06/13 13:18

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

2016/06/14 12:22

完全に雑談になってしまうかもしれませんが、linuxのdevice-mapperはデザインパターンで言うところのデコレータ/コンポジットパターンをアーキテクチャレベルで実現していますね。ある言語内(シンタックスレベル)で閉じたデザインパターンでなく、アーキテクチャレベルでそれをやっていてスゲーというか、関心したことがあります。それを言うならVFSだってそうなんですけども。 うまく表現できませんが、コンパイル時に解消される抽象度ばかりに関心がいっていたので、コンパイルした後にも抽象度を保つ(言語に依存しない)設計や考え方があるんだ、みたいなことをそのとき思いました。デザインパターンは言語に依存しない、というのはこういう意味も含んでいたのか?、と。 リーナス氏がコンパイル時に解消される抽象度(C++のフィーチャー)には興味が無さそうにみえるのは、さらに上の設計レベルの抽象度のことを考えてるからかもしれません(完全に個人的な憶測)。
guest

0

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

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

投稿2016/06/11 23:54

takasima20

総合スコア7458

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

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

投稿2016/06/13 08:48

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

投稿2016/06/12 03:14

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

投稿2016/06/12 02:32

MIURA_Yasuyuki

総合スコア306

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2016/06/14 09:40

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

2016/06/14 14:41

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

0

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

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

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

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

投稿2016/06/12 00:56

編集2016/06/12 01:10
daive

総合スコア2028

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otaks

2016/06/12 02:41

>OOPの為にC++を作ったのに、何故にCで行う必要があるのでしょう? >今や、マイコンの処理系としても、C++は実装されたりしています。 背景の記述不足で申し訳ないですが、一番初めは自分もC++という選択肢を 思い付きました。でも、C言語で開発が続いてきているある業務において 新たな言語を導入できる見込みは以下理由から低いと判断しました。 ・既存エンジニアがC++を使いこなすまで非常に時間がかかる ・既にあるコード規約等はC専用のもの ・お偉いさんが、現状それで回っている環境をわざわざリスクを抱えてまで  新たな道具を導入するとは思えない
daive

2016/06/12 03:47

OSや対象、機能等が不明ですので、なんともですが。 >お偉いさんが >既存エンジニアがC++を が、問題でしょうねぇ。 C++は学習コストが掛る言語系ですので。 ’ 仕事用コードで、コード規約まで存在しているのであれば、 それなりに、Cのコードは機能分けして、モジュール化されていると思いますので、 グラフィック系UIや、ネットワーク、通信系があるのであれば、そっち方面を切出して、 クラス化、オブジェクト化の有用性を、示してみるのは、 価値があるかもしれません。 ⇒全とっかえは、いきなりは出来ないでしょうから、  徐々にCのコードは、ロジックだけにしてしまい、  最終的に、OOP系にしてしまう方向。
otaks

2016/06/12 04:17

全てをOOP化するつもりはありませんが、最低限に必要なところに必要なだけできれば、現状より少しは良くなるのではという淡い期待があります
catsforepaw

2016/06/12 07:59

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

2016/06/12 08:21

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

2016/06/12 09:17

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問