Archive for the ‘C++ 寄稿記事’ Category

C++の新しいキャスト

Monday, April 2nd, 2007

従来のキャストの問題点

異なる型への変換において、C/C++ではキャストが用いられます。

// intからlongへのキャスト
int ival;
int lval = (long)ival;

ご存知のとおり、キャストは非常に危険です。 本来ならば型の不一致によるコンパイルエラーをねじ伏せるのですから。

(more…)

sizeofの不思議

Monday, April 2nd, 2007

はじめに

Cではsizeofによって構造体がメモリ上で占める大きさ(バイト数)を知ることができます。

struct s{
  int x;
  int y;
};
...
cout << sizeof(s) << endl;

僕の愛用する処理系、Visual C++ 6.0では 8が得られました。intひとつにつき4byteを消費するからでしょう。

それではC++でのclassの大きさはどうでしょう。内包するメンバ変数それぞれの占めるバイト数の総和になるのでしょうか。

(more…)

抽象データ型と Java/C++ そして COM/CORBA

Monday, April 2nd, 2007

抽象データ型とは…

  • 抽象データ型
  • 継承
  • 多態

をオブジェクト指向の三本柱などと称しています。その中でも抽象データ型(あるいはデータの抽象化)はオブジェクト指向の最も基本的で重要な概念ではないかと考えます。

"データを抽象化する"とは、データをそれに対して適用できる操作の集合で定義することです。

簡単な例として"カウンタ"を考えてみましょう。カウンタには3つの操作:

  • +1する (increment)
  • -1する (decrement)
  • 現在値を取得する

を提供させることにします。

さて、このカウンタをCで実現するとどうなるでしょうか…

(more…)

9章: クラス RWBTreeOnDisk の使い方

Friday, April 14th, 2006

(more…)

4 章: クラス RWDate の使い方

Friday, April 14th, 2006

(more…)

6章: 仮想ストリームの使い方

Friday, April 14th, 2006

(more…)

付録 B: Typedef とマクロ

Friday, April 14th, 2006

(more…)

A.1 Tools.h++ コレクションクラスの選択

Friday, April 14th, 2006

選択チャートには、コレクションに格納するデータについての質問が含まれています。選択チャートにざっと目を通すことにより、作成するプログラムとそのデータにどの Tools.h++ コレクションが最適であるかが分かります。

A.1.1 選択チャートの使い方

選択チャートを見やすくするために、各選択肢の質問は簡潔になっています。次に、選択肢の質問について解説します。

コレクション内のデータの順序には意味がありますか?

コレクションの中には、コレクション内のデータの位置を制御できるものがあります。例えば、配列やベクトル、およびリンクリストはデータを「順序付きで」提示します。特定の順序で、または数値インデックスに基づいてデータにアクセスする必要がある場合、順序には意味があります。

重複項目を許可しますか?

コレクションの中には、コレクション内にすでに存在している項目と等しい項目を挿入できないものがあります (通常、この種のコレクションはセットと呼ばれます)。別の種類のコレクションには、複数の同一項目を保持する様々な方法があり、重複項目の挿入を許可します。Tools.h++ コレクションには、重複を調べる機構と重複項目を保持する機構の両方が備えられています。

順序付けは本質的なものですか、それとも外部的なものですか?

コレクション内のデータがそれを挿入する方法によって制御される場合は、「順序が外部的に決定される」と言います。例えば、ベクトルやリンクリストは、外部的に順序付けられています。データがコレクションによって使用されるアルゴリズムによって決定された位置に格納される場合は、順序付けは「本質的」です。例えば、格納されたベクトルやバランスツリーは本質的な順序を持ちます。

外部キーによってデータにアクセスしますか?

値とは異なるキーを基準にして値にアクセスする場合、「外部キーによってデータにアクセスする」と言います。例えば、「電話番号リスト」は、電話番号というデータを、名前の形式をとったキーに関連付けます。逆に、「委員会メンバのリスト」は、名前の形をとったデータだけになります。情報を取得するためには、キーを必要としません。

数値インデックスでデータにアクセスしますか?

配列またはベクトルに格納されているオブジェクトには、数値インデックスでアクセスします。例えば、数値インデックス「12」を用いてオブジェクトを見つけ、12
という位置にあるオブジェクトにアクセスします。

自身との比較によってデータにアクセスしますか?

明示的なインデックスやキーのいずれとも一緒に格納されていないデータは、検索データとコレクション内のデータの一致を探すことによって見つけることができます。前述した委員会メンバのリストは、この種類のデータの例です。Set や Bag は自身との比較によってアクセスするコレクションの例です。

自身との比較によってデータにアクセスする場合は、どの種類の一致基準を使用するかを知る必要があります。一致には、あるオブジェクトを別のオブジェクトと直接比較する「等値性」を基準にすることも、オブジェクトのアドレスを比較し、オブジェクトが同一であるかどうかを調べる「アイデンティティ」を基準にすることもできます。

最適のアクセス方式は、リンクノードによるものですか?

リンクノードを利用するコレクションは、通常リストと呼ばれます。リストでは、コレクションの両端にあるデータに素早くアクセスでき、コレクションの真ん中にデータを効率よく挿入することができます。ただし、コレクションの真ん中にあるデータに頻繁にアクセスする必要がある場合、リストは他のコレクションに比べてそれほど効率的ではありません。

頻繁にアクセスするデータがコレクションの両端にありますか?

処理しなければならないデータの量が分からない場合は頻繁にありますが、処理するほとんどのデータは、コレクションの最も新しいデータか、最も古いデータです。最後に追加されたデータを処理するのに最も効率的なのは、「後入れ先出し」方式を持つコレクションです。後入れ先出し (LIFO) のコンテナは「スタック」です。先入れ先出し (FIFO) 方式でデータを処理するコレクションは、「待ち行列」と呼ばれます。最新データと最古データの両方に効率的にアクセスできるコレクションは、「両頭列」あるいは Deque (Double Ended Queue) と呼ばれます。

リンクリストの場合-データにリストの一方からだけ、または両方からアクセスする必要がありますか?

一重リンクリストはサイズが小さいのですが、リストの「正面」からだけアクセスできます。二重リンクリストは、より柔軟性のあるアクセス方式を持ちますが、格納されている各オブジェクトごとに追加のポインタを必要とします。

数値インデックスでアクセスするコレクションの場合-コレクションを自動的にサイズ変更する必要がありますか?

コレクションに格納する項目の最大数があらかじめ分かっている場合は、固定サイズのコレクションを選択する方がより効率的に挿入と削除を行うことができます。反対に、ほとんど無制限に拡張する必要がある場合は、現在格納しているデータ量に合わせて自動的にサイズを調整するコレクションを選択するべきです。

A.1.2 その他の選択基準

どのコレクションを選択するかは、これまでの経験や直観を含め、数多くの要素に依存します。選択チャートの質問の他に、どのコレクションを選択するかを決める上で次の質問も考慮してください。

複数コレクションで単一オブジェクトを保持する必要がありますか?

「はい」の場合は、ポインタベースのコレクションを使用します。

コピーするのに時間のかかるオブジェクトを収集しますか?

「はい」の場合は、ポインタベースのコレクションを使用します。

ポインタベースのコレクションを使用しなければならない理由がありますか?

「いいえ」の場合は、値ベースのコレクションを使用します。

コレクション内のオブジェクトの順序を外部的に制御しますか?

「はい」の場合は、ベクトルやリストなどのシーケンスコレクションを使用します。

挿入後、コレクション内の項目が変更可能である必要がありますか?

「はい」の場合は、シーケンスコレクションまたはマッピング (辞書) コレクションを使用します。マップと辞書は、不変のキーを持ちますが、値は変更可能です。

コレクションがオブジェクトの比較を基準に独自の順序を保持するようにしますか?

「はい」の場合は、セット、マップ、あるいはソート済みコレクションを使用します。

数値インデックスによってコレクション内のオブジェクトにアクセスしますか?

「はい」の場合は、シーケンスコレクションまたはソート済みコレクションを使用します。

非数値キーによって値を検索する必要がありますか?

「はい」の場合は、マップまたは辞書を使用します。

比較するオブジェクトを指定して、コレクション内のオブジェクトにアクセスしますか?

「はい」の場合は、セット、マップ、あるいはハッシュベースのコレクションを使用します。

意味のある順序付けをなしで済まし、その代わりメモリをキーによる定時間のルックアップに使いますか?

「はい」の場合は、ハッシュベースのコレクションを使用します。

必要に応じて拡張または縮小するコレクションで高速のルックアップと挿入が必要ですか?

「はい」の場合は、B-ツリー、あるいは新しい標準 C++ ライブラリを基にした連想コンテナを使用します。

メモリにデータすべてを読み込まずに、アクセスする必要がありますか?

RWBTreeOnDisk または RWTValVirtualArray を使用します。

Graphic1

image21

2.1 具体クラス

Friday, April 14th, 2006

具体クラスは、以下のクラスから構成されています。:

  • 第 3 章から第 5 章で説明されている、日付、時刻、文字列などを表わす単純クラス
  • 第 11 章で説明されているテンプレートベースのコレクションクラス
  • 第 12 章で説明されている、プリプロセッサ &#60;generic.h> を使う汎用コレクションクラス

2.1.1 単純クラス

Tools.h++ には、軽量化された単純クラスが多く含まれています。軽量化されたクラスとは、時間のかからない初期設定子とコピーコンストラクタを持つクラスを意味します。単純クラスには、RWDate (日付)、 RWTime(時刻、各種の時間帯および地域に対応)、RWCString (シングルおよびマルチバイト文字列)、RWWString (ワイド文字)、および RWCRegexp または RWCRexpr (正規表現) などがあります。これらのクラスのほとんどは、4バイト以下で保持することができ、また非常に簡単なコピーコンストラクタ(通常1ビットコピー)を持ち、仮想関数は持っていません。Tools.h++ Class Referenceを参照してください。

2.1.2 テンプレートベースのコレクションクラス

テンプレートベースのコレクションクラス (略してテンプレート) には、速度と型保証という利点があります。しかし、コードサイズを減らすためには、あまり使わないようにしてください。テンプレートは多くの異なる型で使用できますが、各型がまったく新しいクラスを生成するために、コードサイズが大きくなる可能性があります。使用コンパイラで標準 C++ ライブラリが使える場合は、標準 C++ ライブラリをもとにしている Tools.h++ テンプレートベースコレクションを使用できます。使用コンパイラで標準 C++ ライブラリを使えない場合でも、11.3.1節および 11.10 節に説明されている、サブセットのテンプレートを使用できます。

2.1.3 汎用コレクションクラス

汎用コレクションクラスは、C++ コンパイラに付属しているプリプロセッサマクロ&#60;generic.h> を使用するクラスです。このクラスは、テンプレートに対応していないコンパイラに対しては、型保証がされているために、テンプレートとほとんど同じように扱えます。このため、移植性が高いとも言えます。ただし、プリプロセッサにかなり依存しているため、この汎用コレクションクラスを含むコードで、デバッガを使用することが困難になる場合があります。さらに詳しくは、第 12 章を参照してください。

2.2 抽象基底クラス

Friday, April 14th, 2006

Tools.h++ には、抽象基底クラスといろいろな機能のフレームワークを提供する特殊化クラスが含まれています。以下の表は、機能と抽象基底クラスの関係を示したものです。抽象基底クラスの場合は、Tools.h++ Class Referenceの各クラスごとの説明に明記されています。

表 1.抽象基底クラスと機能

機能
クラス
参照箇所
Locale
RWLocale
16.4 節
時間帯
RWZone
16.4 節
仮想ストリーム
RWvistream RWvostream
第 6 章
多形永続性
RWCollectable
第 14 章
仮想ページヒープ
RWVirtualPageHeap
『Class Reference』
モデルビューコントローラ抽象化
RWModel RWModelClient
『Class Reference』