C++

C++は、1950年にデンマークで生まれたBjarne Stroustrup(ビャーネ・ストロヴストルップ)が1985年に作成したプログラミング言語である。仕様の標準として現在のところ5個の標準がある。それぞれの通称は、C++98、C++03、C++11、C++14、C++17である。

言語標準には、標準ライブラリも含まれている。標準ライブラリの一部として、Standard Template Library (STL)がある。STLは、1950年にロシアで生まれたAlexander Stepanov(アレクサンドル・ステパノフ)が開発した。

言語標準は、有料であって無料で公開はされていない。しかし、ほとんど等価な草案は公開されていて、そちらが広く利用されている。どの標準についてどの草案を参照すべきか、cpprefjpというウェブサイトに記載されているようだ。例えば、C++17の標準についてはDocument Number N4659をHTMLで閲覧できる。なお.pdfファイルは1,622ページある。

Hatena Blogでは、Markdown記法が使える。

const correctness

という言葉がある。

律儀にconstを多用すると、かえって面倒なことにならないだろうか? 例えば、class Tを変更しないメンバ関数void print() const;があるとする。しかし、もしprint()した回数を状態として持ちたくなったら、インタフェースの規約に実装が縛られて困るのではないだろうか? あるいは、キャッシュを保持したくなる場合もあるかもしれない。mutableキーワードというものがある。外部に公開しない内部の状態についてはこれを使い、外向きにはconstとする考え方もあるようだ。話が複雑になる気がする。

rule of five

rule of threeあるいはrule of fiveという言葉がある。

  • destructor
  • copy constructor
  • copy assignment operator
  • move constructor
  • move assignment operator

rule of zeroという言葉もある。

exception safety

という言葉がある。David Abrahamsが考案した。

  • No-Throw Guarantee
    • 最も高い安全性。ユーザにとっては正常系しか存在しないように見えるもの。
  • Strong Exception Safety
    • rollbackして元の状態に戻れることは保証されているもの。
  • Basic Exception Safety
    • 例外が発生したとしてもシステムを矛盾した状態にはしないもの。
  • No Exception Safety
    • 最も低い安全性。例外が生じた場合の状態について保証はない。

参考:

copy and swap idiom

という言葉がある。

Joint Strike Fighter Air Vehicle C++ Coding Standards

というものがある。Lockheed Martin社が2005年に定めたもの。F-35のために作られた。F-35より前はAda言語が使われていた。

move semantics

という言葉がある。C++11で導入された。右辺値参照型(T&&)が導入されたことによる。

従来でも、ポインタを陽に使えば同じ性能を出せる。所有権の操作を陰に書けるようにした。

C++には、garbage collectionの機能はない。RAII (Resource Acquisition Is Initialization)によることが原則であり、それで済まないときには、newとdeleteを対応させることを基本にしてきた。garbage collectionの方法には、大きく分けて、TracingとReference Countingがある。shared_ptrは参照カウント方式によるgarbage collectionであり、unique_ptrは、所有者が1つのときのそれだが、JavaのようなTracing方式のgarbage collectionは、言語仕様としては今なお持っていない。その意味で、C++にはgarbage collectionの機能はない。

move semanticsやsmart pointerは、ポインタなどによるboilerplate codeを抽象化して隠蔽し、外見をJavaPythonに似せる方向性なのではないかと思う。しかし、Tracing方式のgarbage collectionが存在しない以上は、参照カウントや所有権といった話になり、プログラマが気にかける事柄は必然的に存続する。

RAII

RAIIを使わずに、オブジェクトの生成と破棄を常にnewとdeleteでやると、C++の基本はずっと分かりやすいのではないだろうか。しかしそれではコードが煩雑になるためRAIIが導入され、連鎖的に、コピーコンストラクタ、さらにはデフォルトの暗黙的なコピーコンストラクタなどが定義された。そのため、smart pointerやmove semanticsが導入される以前から、コピーコンストラクタについてだけでも、C++は少し難しさのある言語になってしまっている気がする。

恐らく、C++の理解が浅いときに起こる問題は、動作がおかしくなるものと、動作が非効率になるものとに分けられるのではないだろうか? 例えばmoveで済むところで、大量のコピーを行っていれば、処理のパフォーマンスが下がるだろう。しかしとりあえずは気にせず、コードを書くことでC++の基本的な機能に慣れていくことのほうが大切だろう。