コンパイル

C++ソースファイルの拡張子は .c または .cpp である。

Sun Solarisでソースファイルをコンパイルするには CC コマンドを使用する。

$ CC sample.cpp

gcc-c++がインストールされていない場合、以下のエラーが出力される。

$ gcc sample.cpp
gcc: error trying to exec 'cc1plus': そのようなファイルやディレクトリはありません

または

$ gcc sample.cpp
gcc: error trying to exec 'cc1plus': execvp: No such file or directory

Red Hat Enterprise Linux及びCentOSでgcc-c++をインストールする場合、yumコマンドを使用する。

# yum install gcc-c++

または

$ sudo yum install gcc-c++

コンパイル時に下記のエラーが出力されるときは、libstdc++をリンクする必要がある。

undefined reference to `__gxx_personality_v0'
collect2: ldはステータス 1 で終了しました
gcc sample.cpp -o sample -lstdc++

標準入出力ストリーム オブジェクト

std::cout

std::coutは、標準出力に関連付けられた出力ストリームオブジェクトである。出力はバッファリングされる。std::coutstd::ostreamクラスのインスタンスで、グローバル変数である。

std::coutはヘッダostreamで定義されているため、std::coutを使用するプログラムはostreamをインクルードする必要がある。ただし、ostreamはヘッダiostreamからインクルードされているため、iostreamをインクルードしていれば、ostreamを明示的にインクルードする必要はない。

#include <iostream>

main()
{
    std::cout << "Hello C++ world!";
}

旧式のC++では名前空間stdは必要ない。この場合はiostream.hをインクルードする必要がある。

#include <iostream.h>

main()
{
    cout << "Hello C++ world!";
}

複数の値を << で区切って並べることにより、複数の値を連結して出力することができる。

改行を行うには、"\n"または std::endl を出力する。

#include <iostream>

main()
{
    int cb = 64;

    std::cout << cb << "bytes" << std::endl;
}

std::cerr

std::cerrは、標準エラー出力に関連付けられた出力ストリームオブジェクトである。std::clogと異なり、バッファリングされない。std::cerrstd::ostreamクラスのインスタンスで、グローバル変数である。

std::cerrはヘッダostreamで定義されているため、std::cerrを使用するプログラムはostreamをインクルードする必要がある。ただし、ostreamはヘッダiostreamからインクルードされているため、iostreamをインクルードしていれば、ostreamを明示的にインクルードする必要はない。

#include <iostream>

main()
{
    std::cerr << "Hello C++ world!";
}

旧式のC++では名前空間stdは必要ない。この場合はiostream.hをインクルードする必要がある。

#include <iostream.h>

main()
{
    cerr << "Hello C++ world!";
}

std::clog

std::clogは、標準エラー出力に関連付けられた出力ストリームオブジェクトである。std::cerrと異なり、バッファリングされる。std::clogstd::ostreamクラスのインスタンスで、グローバル変数である。

std::clogはヘッダostreamで定義されているため、std::clogを使用するプログラムはostreamをインクルードする必要がある。ただし、ostreamはヘッダiostreamからインクルードされているため、iostreamをインクルードしていれば、ostreamを明示的にインクルードする必要はない。

std::cin

std::cinは、標準入力に関連付けられた入力ストリームオブジェクトである。std::cinstd::istreamクラスのインスタンスで、グローバル変数である。

std::cinはヘッダistreamで定義されているため、std::cinを使用するプログラムはistreamをインクルードする必要がある。ただし、istreamはヘッダiostreamからインクルードされているため、iostreamをインクルードしていれば、istreamを明示的にインクルードする必要はない。

#include <iostream>

main()
{
    int a;

    std::cout << "a = ";
    std::cin >> a;
}

旧式のC++では名前空間stdは必要ない。この場合はiostream.hをインクルードする必要がある。

#include <iostream.h>

main()
{
    int a;

    cout << "a = ";
    cin >> a;
}

マニピュレータ

マニピュレータとは、ストリームに対して何らかの処理を加えるためのオブジェクトである。

std::endl

std::endlは、改行文字をバッファに出力したうえ、バッファをフラッシュするマニピュレータである。

使用例:

std::cout << std::endl

std::flush

std::flushは、出力バッファをフラッシュするマニピュレータである。

使用例:

std::cout << std::flush

std::ends

std::endsは、文字列の終端文字 '\0' をバッファに出力するマニピュレータである。

使用例:

std::cout << std::ends

std::ws

std::wsは、空白文字を読み飛ばして入力するマニピュレータである。

使用例:

std::string str;

std::cin >> std::ws >> str;

名前空間(ネームスペース)

namespace宣言

名前空間を定義することができる。

namespace 名前空間名
{
    // 変数や関数の宣言
    // または、関数やクラスの定義
}

名前空間に属する識別子を参照するには、スコープ演算子を使って表す。

名前空間名[::名前空間名...]::識別子

名前空間を定義する例を示す。

#include <iostream>

namespace hello
{
    const char world[] = "Hello C++ world!";
}

main()
{
    std::cout << hello::world << std::endl;
}

なお、プリプロセッサのマクロ定義は常に大域(グローバル)名前空間に属する。

namespace myspace1
{
#define BUFSIZE (256)
}

namespace myspace2
{
#define BUFSIZE (512) // 別の識別子ではなく再定義となる
}

using宣言

using宣言を使って、特定の識別子をスコープ演算子を省略できるようにすることができる。

#include <iostream>

namespace hello
{
    const char world[] = "Hello C++ world!";
}

main()
{
    using hello::world;

    std::cout << world << std::endl;
}

usingディレクティブ

usingディレクティブを使って、特定の名前空間に含まれるすべての識別子を、スコープ演算子を省略できるようにすることができる。

using namespace namespace-name

namespace-nameにはネームスペース名を指定する。

たとえば、using namespace std; とすることで、std::coutstd::cincoutcinと記述することができるようになる。

#include <iostream>

namespace hello
{
    const char world[] = "Hello C++ world!";
}

main()
{
    using namespace std;
    using namespace hello;

    cout << world << endl;
}

オーバーロード

2つの数値を足した値を返す関数を作成するとする。C言語の場合は次のようになる。

int add_int(int a, int b)
{
    int ans;
    ans = a + b;
    return ans;
}

double add_dbl(double a, double b)
{
    int ans;
    ans = a + b;
    return ans;
}

int main()
{
    int    ans_int, a_int = 1, b_int = 2;
    double ans_dbl, a_dbl = 1.1, b_dbl = 2.3;

    ans_int = add_int(a_int, b_int);
    ans_dbl = add_dbl(a_dbl, b_dbl);
}

2つの関数add_intとadd_doubleは共に「2つの数値を足した値を返す関数」である。同じ処理を行う関数であるので抽象的には同じ関数であるが、C言語の規則により、それぞれ別の関数名にしなければならない。

C++のオーバーロードを用いれば、これらの関数(メソッド)を同じ名前にすることができる。

int add(int a, int b)
{
    int ans;
    ans = a + b;
    return ans;
}

double add(double a, double b)
{
    int ans;
    ans = a + b;
    return ans;
}

int main()
{
    int    ans_int, a_int = 1, b_int = 2;
    double ans_dbl, a_dbl = 1.1, b_dbl = 2.3;

    ans_int = add(a_int, b_int);
    ans_dbl = add(a_dbl, b_dbl);
}

どちらの関数(メソッド)が呼び出されるかは、呼び出し側の引数と戻り値の型によってコンパイル時に決定される。

オーバーロードを用いれば同じ関数名(メソッド名)にすることができるが、定義はそれぞれ別々に行わなければならない。C++のテンプレートを用いれば、引数と戻り値の型を抽象化することにより、これらの関数(メソッド)を1つの定義にまとめることができる。

テンプレート

テンプレートとは、型指定パラメータに基づき関数およびクラスを生成するためのしくみです ("パラメータ化型" と呼ばれることもあります)。テンプレートを使用すると、1 つのクラスを各種のデータ型に適用できるので、型ごとにクラスを作成する必要がなくなります。

たとえば、2 つのパラメータのうち大きい方の値を返すタイプセーフな関数をテンプレートを使わずに作成するには、次に示すように一連のオーバーロード関数を作成する必要があります。

int max(int a, int b)
{
    return (a > b) ? a : b;
}

double max(double a, double b)
{
    return (a > b) ? a : b;
}

int main(int argc, char *argv[])
{
    int    max_int, a_int = 1, b_int = 2;
    double max_dbl, a_dbl = 1.1, b_dbl = 2.3;

    max_int = max(a_int, b_int);
    max_dbl = max(a_dbl, b_dbl);
}

テンプレートを使用すると、次のように重複部分を 1 つの関数テンプレートにまとめることができます。

template <class T> T max(T a, T b)
{
    return ( a > b ) ? a : b;
}

int main(int argc, char *argv[]) {
    int    max_int, a_int = 1, b_int = 2;
    double max_dbl, a_dbl = 1.1, b_dbl = 2.3;

    max_int = max<int>(a_int, b_int);
    max_dbl = max<double>(a_dbl, b_dbl);
}

テンプレートを使用すると、型を保証しながらソースコードを大幅に小型化し、コードの融通性を向上できます。

C++標準ライブラリ

std::abs

渡された引数の絶対値を戻り値として返す。

整数の絶対値を求める場合は、cstdlibをインクルードする。

int abs(int n);
long int abs(long int n);
long long int abs(long long int n);
#include <iostream>
#include <cstdlib>

main() {
    std::cout << std::abs(-1) << std::endl;
}

浮動小数点数の絶対値を求める場合は、cmathをインクルードする。

float abs(float x);
double abs(double x);
long double abs(long double x);
#include <iostream>
#include <cmath>

main() {
    std::cout << std::abs(-1.1) << std::endl;
}

std::max

渡された2つの引数の値を比較して、大きい方の値を戻り値として返す。

template <class T> const T& max(const T& a, const T& b);

std::maxの使用例を次に示す。

#include <iostream>
#include <algorithm>

main() {
    std::cout << std::max(1, 2) << std::endl;
}

std::min

渡された2つの引数の値を比較して、小さい方の値を戻り値として返す。

template <class T> const T& min(const T& a, const T& b);

std::minの使用例を次に示す。

#include <iostream>
#include <algorithm>

main() {
    std::cout << std::min(1, 2) << std::endl;
}

std::runtime_error

std::runtime_errorは、例外としてスローされるオブジェクトの型である。プログラムの範囲を超えた事象に起因している、容易に予測できないエラーを報告する。stdexceptヘッダで定義されている。

Boost C++ライブラリ

BoostはC++のコミュニティによって公開されているオープンソースのライブラリである。

Boost C++ライブラリのインストール

Red Hat Linux及びCentOS

Boostを使用するには、あらかじめパッケージをインストールしておく必要がある。

# yum install boost boost-devel

コンパイル時には、Boostライブラリのインクルードディレクトリを指定する必要がある。

$ gcc -I /usr/include/boost sample.cpp

Microsoft Windows

Boost C++ Librariesのサイトから書庫ファイルをダウンロードする。書庫ファイルを任意のディレクトリに展開する。

filesystem、graphparallel、iostreams、mpi、programoptions、python、regex、serialization、signal、system、thread及びwave以外のライブラリはヘッダファイルをインクルードするだけで使用できる。その他のライブラリを使う場合は、ビルドが必要である。ビルドするには、boootstrapとbjamのコマンドを実行する。コマンドを実行すると、stage\libディレクトリにライブラリファイルが生成される。

bjam

bjamは、Boost C++ライブラリをビルドして指定したフォルダにヘッダファイルとライブラリファイルを保存するコマンドである。

bjam [options] [properties] [install|stage]

installを指定した場合は、ライブラリをビルドして、ヘッダファイルとライブラリファイルを指定したディレクトリへコピーする。stageを指定した場合は、ライブラリをビルドして、ライブラリファイルを指定したディレクトリへコピーする。

bjamのコマンドオプションは次のとおり。

link=link-type

スタティックライブラリを生成するか、ダイナミックリンクライブラリを生成するのかを指定する。カンマで区切って両方を指定することもできる。

bjamのlinkオプション
説明
staticスタティックライブラリ
sharedダイナミックリンクライブラリ

bjam link=static,shared

runtime-link=runtime-link-type

Cランタイムライブラリをスタティックリンクするのか、ダイナミックリンクするのかを指定する。カンマで区切って両方を指定することもできる。

bjamのruntime-linkオプション
説明
staticスタティックリンク
sharedダイナミックリンク

bjam runtime-link=static,shared

release

リリース版をビルドする。

debug

デバッグ版をビルドする。

--help

bjamのヘルプを表示する。

--toolset=compiler

使用するコンパイラ言語を指定する。コンパイラのバージョンは自動的に検出するが、明示的にバージョンを指定することもできる。

bjamの--toolsetオプションに指定する値
説明
msvcMicrosoft Visual C++
msvc-8_0Microsoft Visual C++ 8.0
msvc-9_0Microsoft Visual C++ 9.0
intelIntel C++コンパイラ
gccGNU Compiler CollectionのC、C++及びObjective-Cコンパイラ
threading=threading-type

シングルスレッドバイナリか、マルチスレッドバイナリかを指定する。カンマで区切って両方を指定することもできる。

bjamのthreadingオプション
説明
singleシングルスレッドバイナリ
multiマルチスレッドバイナリ

bjam threading-multi

次に示すオプションは、installを指定した場合にのみ有効である。

--includedir=dir

dirで指定したディレクトリにヘッダファイルを保存する。

--lib-dir=dir

dirで指定したディレクトリにライブラリファイルを保存する。

--prefix=dir

インストール先のディレクトリを指定する。dirに指定したディレクトリにincludeディレクトリとlibディレクトリが作られて、ヘッダファイルとライブラリファイルが保存される。

次に示すオプションは、stageを指定した場合にのみ有効である。

--stagedir=dir

dirで指定したディレクトリにライブラリファイルを保存する。

Boostのライブラリファイル名は次の形式で表される。

libboost_name-vc90-option-version.lib

nameはfilesystemやthreadなどのライブラリ名である。optionはライブラリの種類を表している。

Boost C++ライブラリの種類
option説明
mtマルチスレッド版
mt-gdマルチスレッド、デバッグ版
mt-sマルチスレッド、スタティックCランタイム版
mt-sgdマルチスレッド、スタティックCランタイム、デバッグ版
sシングルスレッド版

versionはBoost C++ライブラリのバージョンである。

共有オブジェクト(*.so)にBoostのスタティックライブラリをリンクする場合は、bjamのコマンドオプションに「cxxflags=-fPIC」を指定してBoostライブラリをビルドする。

$ ./bjam link=static --prefix=/home/horiuchi/local cxxflags=-fPIC install
スポンサーリンク