モダンC++とCでの代替手法

C++の名前空間とCの名前の接頭辞

このレッスンでは、C++の名前空間とCの接頭辞の習慣を使って、大きなプログラムで関数名の重複を避ける方法を学びます。

はじめに

大きなプログラムや多くのライブラリを使うプログラムでは、2つの関数の名前がぶつかることがよくあります。C++は名前空間(namespace)、つまり名前を入れる独立した空間でこの問題を解決します。Cには名前空間がないため、Cのライブラリはmath_squareのように名前に接頭辞(prefix)を付けるのが一般的です。

大切なポイント

  • C++の抽象化を学ぶ前に、Cでのやり方を理解しましょう。
  • RAIIと値のセマンティクス(value semantics)で、リソースの持ち主を表しましょう。
  • マクロや型変換より、C++の型安全な道具を優先しましょう。

CとC++のコード例

C
実行 →
main.c
#include <stdio.h>

int math_square(int value) {
    return value * value;
}

int main(void) {
    printf("%d\n", math_square(7));
}
実行結果
49
C++
実行 →
main.cpp
#include <iostream>

namespace math {
    int square(int value) {
        return value * value;
    }
}

int main() {
    std::cout << math::square(7) << '\n';
}
実行結果
49

CとC++の比較

Cの接頭辞math_は名前付けの習慣にすぎず、プログラマーの注意だけが頼りです。C++では関数squareは名前空間mathの中にあり、完全な名前math::squareで呼び出します。コンパイラは違う名前空間の名前どうしがぶつからないことを保証し、長い名前空間に別名(alias)を付けることもできます。

C

Cは名前付けの習慣、コールバック、マクロ、文脈を持つstructを使います。

C++

C++はスコープがはっきりした型安全な抽象化を用意しており、実行時のコストはふつうかかりません。

発展問題

両方のバージョンを実行し、コードを書き換えて、それぞれの言語がもたらす安全性の違いを観察しましょう。

  • まずCで仕組みを書き、その後で対応するC++の機能を使いましょう。
  • 手作業のリソース解放をRAIIに置き換えましょう。
  • その機能がメモリの確保や仮想関数の呼び出しを生むかどうかを確認しましょう。