C++のHello World
第3回は、C++を使ったHello Worldです。C++はC言語を拡張した言語です。たいていのC言語用のプログラムは、C++のプログラムとしてコンパイルしてもそのまま動作します。このため、リスト1のように、C言語用のHello Worldのプログラムをそのまま修正なしにC++のHello Worldのプログラムとすることができます。
リスト1 C言語と同じprintf()を使う方法(cpp_printf.cc)
#include <stdio.h>
int
main()
{
printf("Hello World\n"); ← C言語と同様にprintf()を使う
return 0;
}
C++のコンパイル方法はC言語の場合とほとんど同じです。コンパイラとしてgccを使う場合、実行例1のようにg++コマンド使ってコンパイルします。
実行例1 C++のコンパイルと実行
$ g++ -O2 -o cpp_printf cpp_printf.cc ← g++を使ってC++のソースをコンパイル
$ ./cpp_printf ← 作成された実行バイナリファイルを実行
Hello World ← たしかにHello Worldが表示される
$ ← シェルのプロンプトに戻る
このほか、第1回でC言語用に作成した、fputs()やwrite()関数などを使ったHello Worldのプログラムも、同様にそのままC++のプログラムとすることができます。
iostreamを使う方法
C言語とまったく同じプログラムではおもしろくないため、C++ならではのHello Worldを考えてみましょう。
C++では、C言語のstdioライブラリに代わってiostreamライブラリが標準で用意されています。iostreamを使う場合、標準出力を表すstd::coutに対して、「<<」演算子を使うことにより、文字列を出力することができます。改行文字は、C言語と同様に"\n"で記述してもかまいませんが、C++ではstd::endlを使って改行することができます。
リスト2 iostreamを使う方法(cpp_iostream.cc)
#include <iostream> ← iostreamライブラリを使う
int
main()
{
std::cout << "Hello World" << std::endl; ← 標準出力に「<
変数の動的初期化を利用する方法
C++では、変数またはオブジェクトを定数値で初期化するだけではなく、動的な値で初期化することができます。
変数が関数の外部で静的変数(またはグローバル変数)として宣言されている場合、その初期化処理はmain()関数が呼び出される前に行なわれます。そこで、何らかの静的変数を関数の外部に宣言し、その初期化処理としてHello Worldを出力させることができます。
リスト3は、ダミーの静的変数iを宣言し、その動的初期化を利用してHello Worldを出力させている例です(ここではstd::coutなどのstd::を省略するため、「using namespace std;」の記述を加えています)。coutは、「void *」型(voidへのポインタ)に代入できるため、ダミー変数のiは「void *」型として宣言します。この例ではmain()関数の中では何も行なわず、main()の呼び出し前にHello Worldが出力されます。
リスト3 静的変数の動的初期化を利用する方法(cpp_init.cc)
#include <iostream>
using namespace std; ← coutなどにstd::を付けるのを省略するための記述
static void *i = cout << "Hello World" << endl; ← 静的変数の動的初期化を利用
int
main()
{
return 0; ← main()では何もせずにリターンする
}
ここで、静的変数の動的初期化のタイミングを確認するため、リスト4のようにHelloを静的変数の動的初期化で出力し、Worldをmain()関数内で出力するようにしてみましょう。このようにしても、Hello Worldの順序で出力され、静的変数の動的初期化がmain()よりも前に実行されていることがわかります。
リスト4 静的変数の動的初期化タイミングの確認(cpp_init2.cc)
#include <iostream>
using namespace std;
static void *i = cout << "Hello "; ← 動的初期化では"Hello "だけを出力
int
main()
{
cout << "World" << endl; ← main()では"World"と改行を出力
return 0;
}
静的変数の動的初期化だけを利用すれば、メッセージの出力はprintf()などのC言語の関数を使っても構いません。リスト5はprintf()を使った例です。一般にprintf()の戻り値は利用されることは少ないですが、戻り値には出力した文字数が返されます。そこで、これをダミーのint型静的変数に代入して動的初期化を行わせることができます。
リスト5 静的変数の動的初期化でprintf()を使う(cpp_init3.cc)
#include <stdio.h> ← stdioライブラリを使う
static int i = printf("Hello World\n"); ← printf()の戻り値を動的初期化に利用
int
main()
{
return 0; ← main()では何もせずにリターンする
}
クラスを使う方法
さらに、クラスを使わないとC++らしくない、ということで、クラスを使ったHello Worldを書いてみましょう。
リスト6はHelloクラスを定義し、そのコンストラクタの定義の中でHello Worldを出力している例です。このHelloクラスのオブジェクトを宣言すればコンストラクタが実行され、Hello Worldが表示される仕組みです。せっかくなので、Helloクラスをmain()外で静的オブジェクトとして宣言し、main()では何も実行しない方式にしてあります。
リスト6 クラスを使う方法(cpp_class.cc)
#include <iostream>
using namespace std;
class Hello { ← Helloクラスの定義
public: ← 外部から操作できるようにpublicにする
Hello() { ← コンストラクタの定義
cout << "Hello World" << endl; ← メッセージを出力
}
};
static Hello h; ← Helloクラスのオブジェクトを静的に宣言する
int
main()
{
return 0; ← main()では何もせずにリターンする
}