C++ プログラミングガイド

第 1 章 Sun C++ コンパイラの紹介

本書および関連マニュアル『C++ ユーザーズガイド』で説明する Sun C++ コンパイラ CC は、SPARC および x86 ハードウェアプラットフォームの Solaris 2.5.1、2.6、および Solaris 7 オペレーティング環境で使用できます。Sun C++ 5.0 は、C++国際標準 に記載された言語とライブラリを実装しています。

C++ 言語

C++ は、Bjarne Stroustrup による『The C++ Programming Language』で初めて登場し、その後、より公式な解説書として Margaret Ellis と Bjarne Stroustrup 共著による『The Annotated C++ Reference Manual』(『注解 C++ リファレンス・マニュアル』、トッパン刊、通称「ARM」) が刊行されました。現在は、C++ の国際標準が存在します。

C++ は C プログラミング言語の進化形として設計されています。C++ では、C の効率の良い低水準のプログラミング機能を継承しながら、次の機能が追加されています。

特にオブジェクト指向プログラミングをサポートしたことにより、モジュール性に優れて拡張性のあるプログラムモジュール間インタフェースを設計することができます。また、一連の拡張性のあるデータ型やアルゴリズムを含む標準ライブラリにより、汎用性のあるアプリケーションを効率的に開発できます。

データの抽象化

C++ では、言語で事前定義されたデータ型のように機能するデータ型をプロクラマが独自に定義できます。このような抽象データ型を定義することで、問題に対処するためのひな型を作ることができます。

オブジェクト指向の特徴

C++ におけるデータの抽象化の基本単位である「クラス」にはデータが含まれ、そのデータに対する演算が定義されています。

クラスは 1 つ以上のクラスの特性を継承し、それらのクラスの下位のクラスになれます。この特性は、「継承」または「派生」と呼ばれます。引き継がれたクラス (親クラス) は C++ では「基底」クラスと呼ばれ、他のプログラミング言語では「スーパー」クラスと呼ばれます。子クラスは C++ では「派生」クラスと呼ばれ、他のプログラミング言語では「サブクラス」と呼ばれます。派生クラスは、その基底クラスのすべてのデータを含みます (通常はすべての演算も含む)。派生クラスには、基底クラスにはない新しいデータが追加されていたり、基底クラスとは異なる演算が含まれている場合もあります。

基底クラスを派生クラスに置き換えた形のクラス階層を作ることもできます。たとえば Window クラスは、派生クラスとして、ScrollingWindow クラスを持つことができ、ScrollingWindow クラスは Window クラスの特性に加えてその内容がスクロール可能であるという特性を備えています。そのため、ScrollingWindow クラスは、Window クラスが存在する位置であればどこにでも使用できます。このように代替できる特性を、多相性 (「多くの形式を持つ」という意味) と呼びます。

継承を使用し、多相性を持つ抽象データ型を使って設計されたプログラムを「オブジェクト指向のプログラム」と呼びます。

型検査

通常コンパイラ (実際にはインタプリタ) は、演算とデータの型が適合しているか確かめるために型検査を行います。C++ の型検査は C より厳格ですが、Pascal ほどではありません。Pascal が誤ったデータ型を常に拒否するのに対し、C++ コンパイラはエラーを出力する場合もありますが、ほとんどの場合は適した型に変換します。

もちろん、このような C++ コンパイラによる自動変換のほかに、C と同様に明示的な 「型変換」もできます。

関数名の多重定義についても同様です。C++ では複数の関数に同じ名前を付けることができます。コンパイラは、関数呼び出しの際にパラメータの型を検査して呼び出す関数を決定します。正しい関数がコンパイル時に判定できないと、コンパイラは「曖昧である」という意味のエラーを出力します。

クラスとデータの抽象化

C 言語でプログラムを書いた経験のある方ならば、クラスとは struct の概念を拡張したものを考えるとわかりやすいでしょう。struct には charint のような事前定義されたデータ型が含まれ、他の struct 型が含まれる場合もあります。C++ では、struct 型はデータを格納するデータ型だけでなく、データを操作する演算にも使用できます。C++ のキーワードである class は、C の struct と似ています。使い方としては、多くのプログラマは、C と互換性のある struct 型を表すのに struct を使用し、C では使用できない C++ 機能を持つ struct 型を表すのに class を使用しています。

C++ には、「データの抽象化」の手段としてクラスが用意されています。プログラムのデータとしてどのような型 (クラス) がいいかを最初に決定し、次にそれぞれの型が必要とする演算を決定します。つまり、C++ クラスはユーザーが定義するデータ型と言えます。

たとえば 大きな整数の演算を行う BigNum というクラスを定義する場合、クラス BigNum のオブジェクトと一緒に使用したときだけ意味を持つ + 演算子を定義できます。n1 n2 BigNum という型のオブジェクトである場合、次の式は BigNum で定義した + 演算子によって値が決まります。


n1 + n2

operator +() が定義されていないと、クラスの型に対して + 演算は実行できません。+ 演算子は、intlongfloat などの組み込み数値型に対してのみ事前定義されています。

このように複数の定義を持つ演算子を「多重定義演算子」と呼びます。

C++ クラスのデータ記憶要素は、「データメンバー」と呼ばれます。演算には、関数と多重定義された組み込み演算子 (特殊な関数) の両方が含まれます。関数は、クラスの一部として宣言されたメンバー関数であることもあれば、クラスの外で宣言される非メンバー関数であることもあります。メンバー関数は、クラスのメンバーにだけ作用します。クラスの非公開メンバーまたは限定公開メンバーに直接アクセスする必要がある場合は、非メンバー関数は「フレンド関数」として宣言されなければなりません。

クラスメンバーへのアクセスのレベルは、public (公開)、private (非公開)、protected (限定公開) という「メンバーアクセス指示子」を使って指定できます。公開メンバーは、プログラム内のすべての関数で使用できます。非公開メンバーを使用できるのは、クラスのメンバー関数とフレンド関数だけです。限定公開メンバーを使用できるのは、基底クラスのメンバー関数とフレンド関数、および派生クラスのメンバー関数とフレンド関数だけです。同じアクセス指示子を基底クラスに適用すると、影響を受ける基底クラスのすべてのメンバーに対するアクセスを限定できます。

C との互換性

C++ は、C と高い互換性が保たれるように設計されています。 C のプログラマは C++ を独自のペースで学習し、必要に応じて C++ の機能を統合することができます。C++ では C の長所や便利な点がさらに強化されていますが、特に重要な点は、システムの構成要素に直接関りを持つ型や演算子など、コンピュータのハードウェアへの効率的なインタフェースが、C と同様 C++ でも継承されていることです。

しかし重要な相違点もいくつかあります。普通の C プログラムを C++ でコンパイルするには、多少の修正が必要です。C から C++ へプログラムを移行する場合に注意すべき事項については、『 C++ 移行ガイド』で説明しています。

C と C++ では、プログラムモジュール間のインタフェースを設計する場合に最も大きな違いがありますが、C++ にはそのインタフェースの設計に使用する C の機能がすべて継承されています。たとえば、C++ モジュールを C モジュールにリンクできるため、C++ のプログラムで C のライブラリを使用することができます。

C と C++ ではこの他多くの細かな相違点があります。C++ には次に示す機能があります。