第1回 C++言語:基礎(Cとの類似点、相違点)
(参照オペレータ、入出力ストリームなど)


C++言語に慣れよう

はじめにC言語には十分に詳しいと仮定して C言語とC++言語を比較します。 歴史的にC言語は1970年代にUNIXオペレーティングシステムの記述言語として当時のベル研究所の(現在のAT&T)のDennis Ritchie(リッチー)とKen Thompson(トンプソン)により考案されました。 一方、C++言語は1980年代後半に、 同じくベル研究所のStroustrup(ストロヴストルップ)により、考案されました。 もともとC++言語はC言語の拡張として作成され、 C言語にクラス、仮想関数、オーバーロード(関数と演算子)、 継承、テンプレート、例外処理など多くの拡張がなされました。 その意味では、 C言語で勉強した人にもっとも自然にオブジェクト指向言語の例を学ぶ手段として、 C++言語は1990年代には、 猛烈な勢いで全世界に広まり、 C言語とともに C++言語はISOの国際標準になっています。 TIOBE社の調査によると、 人気度は2019年6月段階では、 Java言語が第1位、C言語が第2位、C++言語が第4位です。 参考までに、人気上昇中の言語としてPython(第3位) があり、 こちらは大学院のデータマイニング特論で授業中の資料で利用します。 なお、JavaもPythonも、まだ国際標準にはなっていません。 一方、C,C++, C#, JavaScript (ECMAScript), FORTRANはISOの国際標準になっています。

以下では、 g++と呼ばれるGNUのC++コンパイラを使ってプログラミングしていくことを前提に述べます。 (注:他にも、マイクロソフトのVisual C++, Borland社のBorland C++, アップル社などが開発したClang (Objective-C++)などがC++言語のコンパイラとして知られています。) C++言語の拡張子に関する世界的な基準は特になく、 歴史的には(.cc)(.C)(.cpp)(.c++)などがよく用いられてきましたが、 本授業では(.cpp)を用いることとします。 たとえば、HelloWorld.cppを作成し、以下のようにコンパイルします。

g++ -Wall -std=c++14 -o HelloWorld HelloWorld.cpp

コンパイラオプションとして警告をすべてプリントする-Wallオプションがついていることに注意してください。また、C++11と呼ばれる-std=c++11オプションもつけたり、それを包含するC++14と呼ばれる-std=c++14オプションもつけたりします。 プログラム1-1では、これらのオプションは特に有意ではないですが、警告オプションならびにC++14(C++11)オプションは、とても重要です。そこでC++言語のコンパイルでは、これらのオプションを必ずつけておくことを勧めます。 プログラムの中身はこんな感じです。
HelloWorld.cpp
1 
2 
3 
4 
5 
6
7
8
/* プログラム1-1 HelloWorld.cpp (プログラムの文字コードはUTF-8を仮定します)*/
#include <iostream>
using namespace std;

int main(void){
	cout << "こんにちは、世界のみなさん!" << endl;
	return 0;
}

g++コンパイラは、C言語のコンパイラgccの拡張にもなっているため、 これまで作成してきたC言語のプログラムを、実は、 そのままg++でコンパイルしてもほとんどの場合、問題ありません。 しかし、C言語でしか定義できない機能 (たとえば可変長配列宣言)を使っている場合は正常にコンパイルできません。 また、プログラム1-1では、 C言語で通常よく用いるinclude文のstdio.hというヘッダーファイルもなければ、 printf関数も使っていません。 その代わりに、 標準ストリーム入出力クラスであるiostreamを使い、 その中にあるcout(出力用標準ストリーム)を使っています。 C言語にたとえると、stdoutに類似します。 これから想像できるかと思いますが、 cinというストリームは入力用でstdinに相当し、 cerrはstderrに相当するエラーストリームに対応します。 iostream自体はヘッダーファイルですが、 (.h)の部分をincludeで付けていないことに注意してください。 また、<< のように、 左シフトと同じ記号での出力演算子使います。 これはシフト演算子の多重定義になっており、 演算子(オペラータ)オーバーローディングと呼びます。 さらに、3行目にあるusing namespace std;は、 名前空間usingディレクティブ用法を使っています。 これは、stdという名前のクラスの関数や変数を、 クラス名を参照しないで直接使います!ということを宣言しているのです。 これがないと、coutはstd::coutと書き、 改行を意味するendlはstd::endlと書かねばなりません。 つまり変数名の前にクラス名ダブルコロン(::)をつける必要があります。

このように、元来はC言語の拡張として誕生したC++言語ですが、 まずは入出力で、iostreamを使うことに慣れ、 これまでよく利用していた、 printfやscanfなどを使うのは (入出力の性能が深刻となる場合を除いて)できるだけ控え、C++らしい入出力に慣れるようにしましょう。 さて、3行目がない場合は、プログラム1-1は以下のようになります。
HelloWorld1.cpp
1 
2 
3 
4 
5 
6
7
/* プログラム1-1A HelloWorld1.cpp (プログラムの文字コードはUTF-8を仮定します)*/
#include <iostream>

int main(void){
	std::cout << "こんにちは、世界のみなさん!" << std::endl;
	return 0;
}

他にも、C言語とC++言語には、様々な違いがありますので、 「オブジェクト指向」が何かを詳説する前に、 代表的な相違点をみていきましょう。


C言語との類似点と相違点

C++言語は、C言語を拡張し、「オブジェクト指向」言語として 位置付けたことを述べましたが、具体的にどういうことなのかを 例を交えて示します。