C ++を使用し、言語固有の機能を使用しない場合、Cに切り替える必要がありますか?


16

趣味としてNESエミュレーターを開発しています。C ++を使用している理由は、私が主に使用している言語であり、ほとんどを知っており、ほとんどの言語が好きだからです。

しかし、プロジェクトにある程度前進したので、C ++の特定の機能をほとんど使用していないことに気付き、プレーンなCでも同じ結果を得ることができたはずです。テンプレート、演算子のオーバーロード、ポリモーフィズム、継承は使用しません。それで、あなたは何と言いますか?C ++のままにするか、Cで書き直す必要がありますか?

パフォーマンスを上げるためにこれを行うことはありませんが、副作用として生じる可能性がありますが、それが必要ないのであれば、なぜC ++を使用する必要があるのでしょうか?

私が使用しているC ++の唯一の機能は、データとメソッドをカプセル化するクラスですが、構造体と関数でも同様に行うことができ、newとdeleteを使用していますが、mallocとfreeを使用することもできます関数へのポインタで達成できるコールバックのためだけに継承を使用します。

趣味のプロジェクトであり、締め切りがないので、書き直しが必要なオーバーヘッド時間と作業は問題ではなく、楽しいかもしれません。だから、質問はCまたはC ++ですか?


3
あなたはすでに自分自身に答えているようです:Cだけが必要なのに、なぜC ++を使うのですか?Cが完全にOKである多くの状況があります。
ジョルジオ

3
@Giorgio:そして、それらはすべて最初の60秒後に蒸発し、コードを維持する必要があります。
DeadMG

7
I use C++ because is the language I use mostly, know mostly and like mostly.そして、それがあなたの質問に対する答えです。現在の言語では解決できない問題がある場合にのみ、プロジェクトの途中で言語を切り替える必要があります。I don't use templates, operator overloading, polymorphism, inheritance.Cに切り替えるよりも概念を学習して使用する方がはるかに価値があります。これは趣味のプロジェクトなので、これまで使用したことのないいくつかのことを使用してみませんか。常にCで別のプロジェクトを開始して言語を習得することもできますが、現在のプロジェクトでは切り替えても意味がありません。
ヤニス

4
私が書いているすべてのプロジェクトでも、言語の100%を使用しているわけではありません。C ++を最もよく知っているので、今まで使用したことがない機能を使用する正当な理由が見つかるかもしれません。あなたは、標準ライブラリのものを使用して起動し、ブースト構築物が好きならば、より安全なCとC ++の治療を開始することができstd::shared_ptrstd::unique_ptrboost::scoped_ptrstd::vectorstd::dequestd::map、あなたを、コールバック関数の場合など、ファンクタの使用を検討して、C ++ 11でラムダ関数などの使用を開始することもできます。
WKL

3
@ジョルジオ:うん。無限のリンクリストをローリングすると、不必要なエラーが発生します。
DeadMG

回答:


40

あなたは今それを使用していないが、あなたはメモリリークが発生またはダブル削除を取得し、次回は、あなたが戻ってくるために物乞いされますstd::vector<T>std::unique_ptr<T, Del>そしてstd::shared_ptr<T>、それらの問題は、ほとんど自明easily-解決することができました。これが、最終的にC ++でCを使用するすべての人に起こることです。賢い人は、バグが現れるのを待たずに移動します。

直接使用するコードはnewdelete実際にはC ++に属していません。「C with Classes」と呼ばれるそのようなハーフハウスに属します。あなたがCを学んだどこ言語は1985年ごろだったということそれはあなたが、単にそれを残念ながら、むしろコモン、より良い教育を非常によく何かを教えなかった++、すべての可能性では2011年ごろ、C ++と特に似てないだろうこれらの機能の使用を見つける。

具体的には、上にリストしたように、C ++の汎用データ構造とリソース管理クラスは、Cが提供するものよりも根本的に非常に優れています。動的に割り当てられた配列が必要な場合は、を使用しますstd::vector<T>。これは非常に一般的な使用例です。それらを使用していない場合、コードは不必要にエラーの大きなリスクにさらされます-特にリソース管理関連。C ++は、Cが決して触れない方法で安全性を保証し、コードを再利用できます。

しかし、あなたも期待しすぎているのではないかと思います。テンプレートと演算子のオーバーロードを記述することは、ライブラリコンシューマにとって一般的ではありません。あなたのコードを使用している場合std::vector<T>、あなたはする必要はありません書く実現するためにテンプレートを。コードでを使用している場合std::string、誰も演算子をオーバーロードすることを強制しません。あなただけにそれらの事をしなければならない書き込み std::vector<T>std::string-しかし、あなたはまだそれらを最大限に活用することができます。

ポリモーフィズム/継承にも特定のユースケースのみがあります。コードでテンプレートを作成したり仮想関数を使用する必要がない場合は、必要ありません。独自のテンプレートを作成する必要がないプログラムまたはプログラムのセグメントがあります。

また、C ++ではCのパフォーマンスは向上しません。


1
@Giorgio:make_shared存在make_uniqueし、同じ仕事をする簡単なテンプレートを書くことができます。より安全です。
DeadMG

4
素晴らしい答え。頭の爪。C ++は、私たちが常に使用しているこれらの小さなライブラリにとって最も価値があります。
アンドレスジャアンタック

2
@Giorgio:そのような複数の引数を呼び出すと、例外の場合にメモリリークが発生する可能性があり、make_sharedより効率的であるため、安全ではありません。工場機能のみが保証された例外安全性を提供できます。
DeadMG

6
@ tp1:WT​​F?英語でお願いします。
DeadMG

2
@Lohoris常識的な引用は必要ありません。CはC ++よりもどのようにパフォーマンスが向上しますか?
クリスは、モニカを復活


6

別の方向から見ます。Cでコードを書き換えることで何かをられますか?純粋に趣味のプロジェクトでさえ、そのような書き直しに関連するコストがあります。機会費用と呼ばれるものが他に何もないとしたら、つまり、Cで書き直して時間を無駄にしないなら、その時間に他にできたはずのことです。

結論:C ++へのアクセスが本当に制限されている(または存在しない)環境でコードが使用される可能性が本当に高いと思わない限り、せいぜい無意味な時間の無駄です。少なくとも私の経験では、それは通常、それを非常に迅速に超えてます.Cに変換する必要があったC ++で記述したコードを振り返ると、かなりの場合でも、それは簡単なはずです、私は最初に実現したよりも多くのC ++固有の機能を使用していました。まったく有用であることを期待するには、C89 / 90をターゲットにする必要があります。その場合、ブロックの実際の場所ではなく、ブロックの先頭ですべての変数を定義する必要があることをすぐに思い出します。中古。

要するに、Cでの書き換えが本当の利点をもたらすと確信しているのでない限り、やるべきことはほとんどあります。


+1少し前に、別のCプロジェクトで使用するライブラリを作成しなければならなかったので、Cでも実装するのは良い考えだと思いました。
クリスは

1

より一般的な答えとして:

よりユニークな機能の一部を使用しているという理由だけで、C ++に切り替えないでください。ある日、これらの機能が必要になる場合がありますが、Cを使用しているため頭を痛めます。


1

趣味の開発では、プレーンなCに戻すことを検討します。CやCのような言語は、小さな趣味の開発モジュールでサポートされる可能性が高くなります。

ここでの答えの多くは、プロのソフトウェアタイプからのものである可能性があります。愛好家として、継続的またはフルタイムでコーディングすることはありません。そのため、プロジェクトを1年間表にして、コーディングでさびた後に戻ってコードを読む場合は、どの言語を覚えているか、癖を忘れやすいかを検討してください。豊富な機能セットを備えたC ++は、コーディングスタイルによっては、再取得に多少の時間がかかる場合があります。


1

あなたの質問に答えるのは簡単ではありません。あなたの言語特有のスキルを向上させるためにプロジェクトに取り組んでいるのか(C対C ++)、他のプログラミングスキルを向上させるのか(デザイン、問題解決など)

「私が使用しているC ++の唯一の機能は、データとメソッドをカプセル化するクラスですが、構造体と関数でも同様に実行できます。」本当じゃない。structsCではカプセル化をサポートしておらず、関数(メソッド)を含めることはできません-少なくとも関数へのポインターなどの手法を使用しないとできません。また、Cの関数はオーバーロードできないため、より脆弱です。

「newとdeleteを使用していますが、mallocとfreeも使用できます。また、関数へのポインターで実現できるコールバックだけに継承を使用しています。」deadmgが述べたように、直接newおよびdeleteC ++ で使用することは推奨されません。また、OOPのIMHO(およびGoF)継承は、多型が必要な場合にのみ、合成よりも優先されるべきです。そして、関数へのポインターを使用してCで多態性(遅延バインディング)を達成することは簡単ではないと思います。

それ以外は、C ++がCよりも「優れている」ことをあなたに納得させようとはしません良いアイデア)。


1
structs実際、Cではメソッドをカプセル化するために使用できます。関数ポインターの構造体を作成し、必要な関数を指すように初期化するだけです。例については、lxr.linux.no / linux + v3.3 / include / linux / fs.h#L1598ご覧ください。
ロバートマーティン

そのとおり。コメントをありがとう、答えを広げました。
サキスク

いいね もう1つの注意点:Cの関数はオーバーロードすることできます(考えprintfてみてください)が、そうすると型チェックが失われます。許容可能な宣言の有限セットを持つ方法はありません。それは1(およびタイプチェックを取得します)または「多数」(そして大きな個人的リスクですべてのタイプチェックを失います)のいずれかです。Cのほとんどのものと同様に、それは可能ですが、しばしば不快です。
ロバートマーティン

関数へのポインタは高度なCテクニックですか?本当に?
ドナルドフェローズ

@DonalFellowsあなたは正しいです、私は誇張しました。高度な削除... :)
sakisk

0

私は非常に初心者なので、ここに私の2ビットがあります。

私はWibit.netでCとC ++をいくつかのすてきな基本的なビデオチュートリアルで学んでいます。多分彼らはあなたが「状況」(広告ではなく!)

あなたが趣味であるので、ただ学ぶためにCに変更することをお勧めします。これは問題ではなく、喜びです。

もっとアドバイスします。両方の言語で行います。見つけて使用する方法とソリューションを比較してください。私はあなたが期待しているほど「簡単」ではないことを確信しています...


1
どうもありがとうございましたが、私は学習していません。CとC ++をすでに知っています。この特定のプロジェクトにどちらを使用するかを尋ねています。
ペトルザ

おっと、学ぶ時間です!= P
H_7

1
また、ビデオチュートリアルの代わりに、KerniganとStroustrupの本、素晴らしいIDE(Visual Studio、Eclipse、Xcode)を入手し、サンプル、試行錯誤をコーディングし、stackoverflowに頼って学ぶことをお勧めします。
ペトルザ

-1

C ++とCの長所と短所を次に示します。

  1. Cに移行すると、選択したC ++サブセット内にとどまりやすくなります。これは、コンパイラの外に出るとコンパイラーがエラーを出すためです。主な問題が決定されたサブセット内に留まることである場合、この代替手段を選択する必要があります。(これをサポートするコンパイラがないのはなぜですか?)
  2. 選択したc ++機能サブセット内にとどまることができたら、次はサブセットを変更して、コードを壊す悪い慣習を取り除くようにします。これには、c ++全体を使用する必要があります。
  3. 「サブセット内に留まる」と「それは良いサブセットです」の両方を取得したら、c ++機能の外側に移動して、要件について考え始めます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.