C++11
C++03では、コンストラクタは他のコンストラクタを呼び出せず、各コンストラクタでクラスメンバの初期化を全て行わなくてはならない。これはしばしば初期化コードの重複を招く。また、基底クラスのコンストラクタは、派生クラスに直接は公開されない。つまり、基底クラスのコンストラクタと殆ど同等であったとしても、派生クラス側でコンストラクタを定義する必要がある。他にも、constでないデータメンバは、メンバの宣言時に初期化できず、コンストラクタで初期化しなければならない。
C++11では、このような問題点に対する解決策が提供された。
まず、C++11では、コンストラクタが他の同等なコンストラクタを呼び出すこと(委譲)が可能になった。これにより、コンストラクタが他のコンストラクタを最小のコード追加で利用できるようになる。他の言語(Java等)では、既にこれを取り入れているものもある。
構文は以下のようになる:
注意すべき点として、C++03では1つのコンストラクタの動作完了と同時にオブジェクトの構築は完了していると考えることができていたが、C++11では一度のオブジェクトの構築に全てのコンストラクタが動作完了しなければならない、と考えなくてはならない点である。複数のコンストラクタが動作することを認めるので、委譲を行う各コンストラクタは完全に構築が完了したオブジェクトに対して動作することを意味する。
C++03では、ユーザーが基底クラスの仮想関数をオーバーライドする際、誤って意図に反する新しい仮想関数を作成する可能性がある:
派生クラスDerivedを設計したユーザーは、Base::some_funcおよびBase::on_errorをオーバーライドするつもりで記述したが、それぞれ引数の型や関数名(シグネチャ)が異なるため新しい仮想関数が生成される。上記はC++コードとして誤りではないためコンパイルエラーにならず、間違いに気付くことができない。
C++11では、overrideキーワードの導入により、このような問題が解消された:
overrideキーワードで修飾された仮想関数が、基底クラスのオーバーライド先と一致するかどうかをコンパイラがチェックし、一致しない場合にエラーを報告する。
overrideの他にfinalキーワードがある。finalで修飾された仮想関数のオーバーライドは許可されない。
C++03では、定数0に、整数定数とヌルポインタという2つの役割が与えられている(この振る舞いは、Cの黎明期(1972年)から続いている)。
長い間プログラマは、0の代わりに定数NULLを使って、この潜在的な曖昧性を大体は回避してきた。しかし、C++になされた2つの設計上の選択が、新たな曖昧性をもたらした。Cでは、NULLはプリプロセッサマクロであり、((void*)0)か0と展開されるよう定義されている。C++では、void*型から他のポインタ型への暗黙の変換は認められないので、Cの1つ目の定義と同じくNULLを定義すると、char *c = NULLのような単純な例でもコンパイルエラーになる。これを修正するため、C++ではNULLは0へと展開される。0は、あらゆるポインタ型への変換が特別に認められているのである。この結果、オーバーロード機構と酷い相互作用を引き起こす。例えば、以下のような宣言があり
foo(NULL)として呼び出す場合、foo(int)の方が呼ばれることになる。この挙動は、多くの場合に意図されたものではない。
新標準では、ヌルポインタを指定するためにのみ予約された新たなキーワードnullptrが導入される。nullptrは整数型との比較や代入はできないが、あらゆるポインタ型との比較・代入ができる。
互換性のため、0の現行の機能も残されるが、この新構文が上手くいけば、C++委員会は0とNULLをヌルポインタとして使用することを非推奨と宣言し、意味の重複を排除するであろう。
C++11には、透過的ガベージコレクションの機能は直接には導入されない。代わりに、C++11標準には、C++でのガベージコレクションの実装を容易にする仕様が導入された。
完全なガベージコレクションのサポートは、もっと後の標準やTechnical Reportに回されることになった。