C++を覚えようとして何度か挫折してもなんとか最初の第一歩を踏み出した話

なんでか今更C++を覚えようとしています。

学習時の私の状況

  • 普段、仕事で利用している言語はC#。
  • 最近、オブジェクト指向がわかってきた若造。でもまだ全然。オブジェクト指向難しい。
  • C言語は、O’Reillyの実践Cを読んだ程度。
  • Scalaにも興味あったけどJavaだから止めた。

C++を覚えようとした理由

  • オブジェクト指向の本を読んでいるとC++の例が多い
  • C++にちょっと憧れていた
  • オブジェクト指向の主言語として覚えたい
  • WindowsでもMacでも共通の言語を使いたい
  • なんだかんだ、息が長い言語。

現在に至までの学習の流れ

  • Effective C++を購入して読む。
  • 全然理解できない。挫折。(2時間くらい)
  • インターネットの教材を探し、ロベールのC++教室というサイトを見つける
  • ロベールのC++教室は、C++を全て網羅的に教えてくれるサイト。効率が悪すぎる。断念。(3時間くらい)
  • もっと抽象的でもいいので、C++の概念が知りたい。まずは使ってみたい。それをとっかかりに継続して学習したい。
  • C++の絵本を購入。概念がすっと頭に入ってきた。素晴らしい。ここでC++への嫌な印象が消えた。(読了に5時間程度)
  • C++怖くない!

C++への印象

  • 昔からある言語なのでモダンな書き方は期待していなかったけど、全然そんなことなかった。ちゃんとマルチパラダイム。積極的に色々な機能を取り入れていて、進化している模様。それでもさすがに節々に古臭さは感じる。そこは仕方ない。C#はいい言語なんだなと再確認。
  • C++は強力な言語。
  • 強力な分、わりと色々な書き方ができるので闇が生まれるのかなと思った。その意味でPythonと全く違う。たぶん、人によって全く違うスタイルで書ける。
  • C++の学習コストが高い。しかも、その理由はいくつかあると思う。
  • C++と直接関係ないけど、WindowsもMacもそれぞれ素晴らしいIDEが使える。Visual StudioとXcode最高です。

C++の学習コストが高いと思った理由

  • C++を学習する上で、C言語を習得済みであることが暗黙の了解みたいな感じ。そのため学習コストが高い。ここにはポインタ等の話も含まれる。ちょっとC言語をかじっていてよかった。
  • C言語等を含む前提知識や、C++独特のイディオムが多い。世間的にはEffective C++を読んでいる事が前提。しかもそれを知らないと割と致命的な欠陥となり得る。やばい。
  • ちゃんとC++を理解するには、オブジェクト指向を理解している必要があるかもしれない。でないと、「この機能は何に使う?」となると思う。すとんと腹に落ちない。そしてオブジェクト指向がそもそも学習コストが高い。難しい。
  • 機能が多い。他の言語であまり見ない機能もある気がする。そして強力な分、複雑だったりする。

これからの学習

  • Effective C++を読み直す。再挑戦。
  • デザインパターンをC++で書いてみる。知識を技術に落とし込む。



「C++を覚えようとして何度か挫折してもなんとか最初の第一歩を踏み出した話」への2件のフィードバック

  1.  お節介かもしれませんが、仕事でC#を使っているなら、わざわざC++の恐怖の深淵をのぞき込む必要はないと思います。Scalaのほうがよっぽどいい言語だし、為になります。せめて、Cをみっちりやってからのほうがいいです。理由は次の通り。
    ・まず第一に、C++やCは落ちます(コアダンプして強制終了)。そういう時、ソースのみから原因を見つけられなければ、コアファイルの解析(デバッガによるスタックトレース等)という作業を行う必要があります。この作業は時として、C言語やC++言語が「どのように機械語にコンパイルされているのか」まで理解できていないと、原因の究明が難しいというケースを伴います(たいていの場合、C++のバイナリはCよりずーーーっと煩雑です)。ようするにC++は、高級言語だといいつつも、結局は面倒な代物なのです。ポインタという糞がしぶとく仕様の中で生き残っているのも(互換性や効率のためであるのは理解していますが)その証拠の一つです。
    ・第二に、C++が「使える」場面は非常に限定的です。ものすごく「大規模」で、「複雑なデータ構造」を、「高速」で処理したい場合に限り、真に「使える」言語です(ブラウザのレンダリングエンジンとか)。そして高速なコードを書くためには、オブジェクト指向だけではなく、テンプレートの仕組み等も理解する必要があるのですが、あれは実用的な反面、まったく楽しいもではありません(テンプレートが如何に腐っているかを学ぶ最良の教材はSTLライブラリです。の中身を見てみましょう。C#のようなまともな言語を使っている人なら、軽度の吐き気に見舞われるはずです。ただ、あなたがもし、そういったものを好きになれるなら、多分boostとかも好きなタイプなのでしょう。その場合、C++はあなたにうってつけの言語です)
    ・第三に、仕様が煩雑すぎるのに、それをきちんと理解していなければ、容易く間違いを犯してしまう点です。たとえば、デストラクタで不用意に例外を発生させる関数、メソッド、そのたもろもろを呼んではいけない、std::shared_ptrは循環参照があるとメモリ・リークする、多重継承したクラスを基底クラスにキャストするときはstatic_castを利用しなければならない、テンプレートの部分特殊化に関する面倒なルール(これは、コンパイル時に発覚するので軽傷で済みますが、面倒臭ささではピカイチ)などです。要するに、どこぞの方が言っていたように「C++でコーディングするには、人生は短すぎる」のです。
     私はC++を数年利用していますが、はっきり言って「非常に強力であり、非常に不愉快な言語」だと思っています。難しいのではなく、不愉快なのです。C#ではちょっと解けそうにない複雑な課題を解きたい・・・というのならSchemeやらHaskellやらがあります。C#使いならPython、Ruby、Lua等にはあまり興味がわかないかもしれませんが、Scalaは割といいんじゃないでしょうか(JavaVMで動くってだけで、糞まみれのJavaとは一線を画すまともな言語です。まあ、言語としてはJavaのほうがC++よりずっと愉快ですけど)。
     そんなわけで、ブラウザエンジンのコア(とか)ゲームエンジンのコア(とか)とりわけ、C++のコンパイラ(とか)を作る予定がないなら、ほかの言語を学んだほうが有意義な時間を過ごせると、私個人としては思います(ただし、上記のようなプログラムを効率的に書こうと思ったら、残念なことにC++は多分一番の選択肢です。特にC++のコンパイラなど。なにしろ複雑でのろいので)。
     結局、複雑なプログラムでも速度を気にしないなら、C++よりマシな言語はいくらでもあります。よって、C++を使うのは「速度」、「メモリ効率」を重視する場合「のみ」なのですが、C++で速くてメモリ効率のいいプログラムを書こうとすれば、めちゃめちゃ面倒なことになります。そして実際問題、そういった場合でもCで事足りる場合がほとんどです(小規模なドライバなど、簡単なデバイス依存のプログラムをC++で書くメリットはゼロです。ライブラリの互換性、コンパイラなどの影響で移植性も低下するし)。考えてみてください。Linuxのカーネルは、ほとんどCで書かれてるんですよ。たいていの場合、必要悪はCだけで十分だっていうこれ以上ない証拠です。C++をやるくらいなら、まずCをやって、効率が必要な部分はCで書き、それ以外の部分はもっと愉快な言語(C#とかScalaとかluaとか)で書くのがベストです。C#使いなら、特に関数型言語など、新鮮でいいと思いますよ。
     

  2. @通りすがりさん
    非常にありがたいコメントありがとうございます。
    実はこの記事を書いてからしばらくC++を書いていて、「この言語やばい」と感じてました。その正体がはっきりわからなかったのですが、「非常に強力であり、非常に不愉快な言語」という表現を聞いてやっと理解しました。まさにその通りだと思います。
    その後、なんだかんだでPythonに興味を持ちました。まだ慣れないですが、軽量言語として楽しんでいます。
    ScalaやHaskellを少し調べてみましたが、とても興味が湧きました。C#でも最近、Linqなどで関数型由来のものがあるのですが、そもそも関数型では思考がまるっきり違うようですね。面白そうです。
    実はC++をこのまま学習し続けるか迷っていたのですが、コメントをいただいて吹っ切れました。必要とならない限り、もう手を引きます。ポインタなどは非常に勉強になりましたが、確かにこれ以上深淵を覗いても辛いだけだとわかりました。貴重な助言をいただき、本当にありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax