const - みる会図書館


検索対象: UNIX MAGAZINE 1992年5月号
5件見つかりました。

1. UNIX MAGAZINE 1992年5月号

連載⑦オフシェクト指向の世界 酉改」のあいだで要素ごとの上交がおこなわれる。 b001 operator = = (const StrEdArray & ) const ; b001 operator ! = (const StrEdArray & ) const ; メンバー関数 IsEmpty() は、配列中の要素がすべて空 ならば TRUE を返す。 b001 IsEmpty ( ) const 21 2 つの文字列配列の加算を定義する ( 要素ごとの連結 ) 。 このとき、 2 つの配列のインデックスの下限と上限か 1 司し でなければならない。 22 St rEdArray operat or + (const StrEdArray & ) const ; 23 文字列配列のメンバー関数 演算子 + = は、直を対象とする場合との一貫性を保っ ように定義する。 構築子によって酉冽を初期化する。 StrEdArray &operator + = (const StrEdArray & ) ; 40 StrEdArray : : StrEdArray (const int from, const int tO , const StrEd &ival) { 41 文字列を文字列配列に加算する ( 文字列は、演算対象と インデックスの下限と上限を設定し、文字列酉改」の領域 なる配列クラスと同し下限と上限をもつ配列として扱われ を石呆する。 る ) 。 from_index = ; 26 StrEdArray operator + to_index = to; (const StrEd & ) const ; 27 array = new StrEd CLength() ] ; Reverse ( ) メンバー関数は、逆順の配列を返す ( イン すべての要素のネ月値が空文字列なら、ここで初期化は デックスの位置を反転するが、下限と上限は変わらない ) 。 終了である。というのは、クラス strEd の省田の構築 StrEdArray Reverse ( ) const ; 子 ( 前述の取 e 呼出しの一部として呼び出される ) はす でにすべての配列要素を空文字列に初期化しているからで sort ( ) はソートされた配列を返す。 ある。 StrEdArray Sort ( ) const ; 29 if (ival こからは、 StrEdArray のプライベート部である。 return ; private : すべての配列要素をネ月化する。 酉改」の下限と上限のインデックスかオ褓内される。 for (int i = from—index ; i く = to—index ; i 十十 ) int from_index ; array [i] ival ; int to_index; 任意のインデックスが使えるようにしたいので、ユー コピー構築子によって配列の領域を確保し、すべての要 サーか指定したあらゆるインデックスを、、べースが 0 " の 素をコピーする。 インデックスに置換する変換関数が必要になる。このメン 51 StrEdArray : : StrEdArray (const StrEdArray (A) { 52 ー関数は、ユーサーカ甘旨定したインデックスの有効 / 無 53 from_index = A . from_index ; 効を最初に調べるようになっている。 54 to_index A . to_index ; array = new StrEd [Length() ] ; 5 5 int Trans1ateIndex (const int) const ; 33 for (int i = from—index ; 56 i く =to_index; i 十十 ) 5 7 酉改」自体は重加勺に割り当てられる。そして、 array CTransIateIndex(i) ] これが配列 58 A. array [Trans1ateIndex (i) ] ; 59 を表すポインタである。 34 StrEd *array; 7 8 9 0 演算子くくを次のように定義したので、文字列配列本 か書き出せる。 36 ostream & operator くく (ostream &s, const StrEdArray (A) ; 37 次の演算子は、文字列と文字列配列を加算する ( このよ うに加算すると、文字列はその文字列を初期値とした配列 に刻長される ) 。 38 StrEdArray operator + (const StrEd &s , const StrEdArray (a) ; 39 24 25 28 45 46 30 7 8 9 0 31 32 82 UNIX MAGAZINE 1992.5

2. UNIX MAGAZINE 1992年5月号

連載②オフジェクト指向の世界 を返す。 代入演算子は、 *this を参照として返す点を除き、 代入先が同しである場合には何もしない。 62 (const StrEdArray (A) { 61 StrEdArray& StrEdArray : : operator ピー構築子とほとんど同じである。 コ 8 7 88 89 90 91 92 93 94 int StrEdArray : : operator ロ (const StrEd& s) const { return from—index—l ; return i ; if (array[Trans1ateIndex(i)] i く =to_index ; i 十十 ) for (int i = from—index ; 63 64 if (this return *this ; 代入先が異なる場合は、次のようになる。 from_index = A . from_index ; A . to_index; to_index array = new StrEd [Length ( ) ] ; こで、酉冽自体をコピーする。 68 for (int i from_index ; i く =to_index ; StrEdArray クラスのための new : 寅算子を示す。十分 なメモリが使えないときは終了 (exit) する。 95 void * StrEdArray : : operator new 土十十 ) 69 70 array CTrans1ateIndex (i) ] = A. array [Trans1ateIndex(i) ] ; 連続代入を可能にするために * t s を返す。 return *this ; デックス境界を返す。 次のメンバー関数は、配列オプジェクトの上限のイン return from_index ; 76 int StrEdArray : : LowerIndex ( ) const { デックス境界を返す。 次のメンバー関数は、配列オプジェクトの下限のイン return (to—index ー from—index 十 1 ) ; 73 int StrEdArray : : Length() const { 次のメンバー関数は、配列オプジェクトの長さを返す。 96 97 98 99 100 101 102 103 111 110 109 108 107 106 105 104 (const int (e) { if ()e ← 0 ) { こで、メモリ不足かどうかを調べる。 : new char [le * sizeof (StrEdArray) ] ; VOid *P = exit(l); (const int (e) , 1e く = 0 , exit . \ Ⅱ " cout くく "StrEdArray : : operator new ・ " くく return p ; exit(l); out Of memory, exit. \ Ⅱ " (const int (e) . cout くく "StrEdArray : : operator new if (p = = NULL) { 2 つの配列の同一生を調べる。インデックスの下限と上 限か伺しか否かて判断する。 112 b001 StrEdArray : : operator 79 80 int StrEdArray : :UpperIndex ( ) const { return to_index ; インデックス演算子は、適切な配列要素の参照を返す。 演算子を x[i] =y[j] のように、式の右辺だけではなく左 辺でも使えるようにするために参照カ芍区される。 Trans1ateIndex() は、適切なインデックスの変換お よひオ査をおこなう。 82 StrEd &StrEdArray : : operator ロ 113 114 115 116 117 125 124 12 3 12 2 121 120 119 118 (const StrEdArray (r) const { if (from—index ! = て . from—index) return FALSE ; if (to—index ! = r. to_index) return FALSE ; こで、要素ごとの上交をおこなう。 return TRUE ; return FALSE ; r. array [Trans1ateIndex (i) ] ) if (array CTrans1ateIndex(i)] ! = 土く =to_index; i 十十 ) { for (int i = from—index ; 演算子 ! = は前記の演算子 = = を使用する。 126 b001 StrEdArray : : operator ! = 83 84 85 (const int i) { StrEd *p = array + Trans1ateIndex(i) ; return (*p) ; 127 128 129 (const StrEdArray (r) const { return ! (*this = = r) ; 次は迅想酉改」アクセスである。これは与えられた文字列 に対応する最初のインデックスをみつけ、一致した位置を 返す。文字列がみつからなけれは、最小インデックスー 1 UNIX MAGAZINE 1992.5 配列は空か ? つまり、配列には空の文字列だけが含ま れているのだろうか ? 130 131 b001 StrEdArray : : IsEmpty() const { from_index ; fO て (int i 83

3. UNIX MAGAZINE 1992年5月号

オフツェクト指向の世界 Stephan von Bechtolsheim はじめに 今回は、文字列からなる要素を含む配列クラスについて 。ここで定義する酉リクラスを使えば、クラスまた は定斉みの型を要素とするような通常の配列ではできな いことが可能になる。 こでは、クラスの酉改」要素に文字列を使用する。酉リ クラスのメンバー関数の多くは、あらゆる配列クラスで実 装されるが、一部は文字列配列クラス固有のものである。 また、汎用の酉改」クラスを定義する際の問題点にも簡単 に触れる。 配列クラスのヘッタ ます、いくっかの . h ファイルをロードする必がある。 今回は酉リの要素を StrEd 型にするので、 strEd のヘッ 5 public : 4 class StrEdArray { こからがクラスのヘッダである。 3 #include "StrEd . h" #include <stream . h> 2 1 #include く b001. 五 > ダファイルは必彡頁である。 ( 省は文字列カ啌 ) カ甘旨定できる。 範囲となる。また、構築子によって配列要素の初期値 たとえば、 [ ー 3..4 ] というのも有効なインデックスの ・インデックス範囲の下限を 0 以外にすること 範囲内にあるか否かの検査 ・配列要素にアクセスするすべてのインデックスが、指定 定すると、次のようなことができる。 クス ( 下限と上限 ) を指定しなければならない。これを指 このクラスの構築子では、酉リオプジェクトのインデッ 第 7 回 文字列配列クラス き コピー構築子と同様、代入演算子も配列のコピーを作 StrEdArray (const StrEdArray&) ; するだけではなく、実際に配列のコピーを作る。 9 10 る。 StrEdArr ay& oper at or (const StrEdArray & ) ; 6 7 StrEdArray (const int from , const int , const StrEd &lval コピー構築子は、 C + + の配列を表すポインタをコピー UNIX MAGAZINE 1992.5 Length() 関数は、配列の要素数を返す。 Lower- lndex ( ) 関数は ( 配列の構築子か呼び出された時点での ) 最小のインデックスを返し、 UpperIndex() 関数は最大 のインデックスを返す。 int Length() const ; int LowerIndex( ) const ; int UpperIndex() const ; インデックスか整数ならば、普通の配列を操作するとき と同様に、演算子口を使って酉改」要素にアクセスできる。 StrEd &operator ロ (const int) ; 演算子ロのインデックスが strEd 型の文字列の場合、 配列のなかで文字列引数に一致する文字列か探索される。 配列のなかに一一致する文字列がみつかれば、その文字列の インデックス位置か返される ( 一致する文字列か複数ある 場合には、最初に一致した位置カ亟される ) 。 文字列がみつからなかったときの戻り値は Lower- lndex() ー 1 である ( この値は境界外なので、一致する 文字列があったかどうか区別できる ) 。 int operator ロ (const StrEd & ) const ; 演算子 new を多重定義する。この演算子は、 str EdArray のオプジェクトを重加勺に割り当て、十分なメモ リが使用できないときには異常終了する ( つまり、けして NULL を返さない ) 。 void* operator new (const int) ; 関係演算子 = と ! = を定義する。インデックスの下 限と上限とが一致しなければ、 2 つの配列はつねに異なっ たものとして扱われる。下限と上限が一致すれば、 2 つの 14 15 16 81

4. UNIX MAGAZINE 1992年5月号

連載⑦オプジェクト指向の世界 132 133 134 135 136 i く =to—index; i 十十 ) if (array [Trans1ateIndex (i)] return FALSE ; return TRUE ; ごとのコピーを実行する。 2 つの文字列配列を連結する。配列の大きさが一致しな い場合は終了する。 137 StrEdArray StrEdArray : : operator + 177 178 179 180 181 182 183 184 192 191 190 189 188 187 186 185 StrEdArray StrEdArray : : Reverse ( ) const { StrEdArray ret (from—index , to—index) ; StrEdArray *p = &ret ; for (int i = from—index ; i く = to—index ; 土 + + ) { StrEd xx = array [Trans1atelndex (from—index + to—index ー i)] ; from_index 十 to—index ー 1 ; int 」 ret [i] XX ; 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 (const StrEdArray & て ) const { if (from—index ! = r. from—index) { cout くく "StrEdArray StrEdArray : exit(l); exit\n" cout くく” incompatible to—index¯es , (const StrEdArray) const : operator 十 cout くく "StrEdArray StrEdArray : if (to—index ! = r. to—index) { exit(l); exit\n" cout くく " incompatible from—index¯es , operator 十 (const StrEdArray) const : return ret ; ソートされた配列を返す。 StrEdArray StrEdArray : : sort ( ) const { StrEdArray ret (*this) ; fO て (int i = from—index ; i く to_index; i 十十 ) { 最小の要素のためのネ月イ 193 int smallest—index 最小の要素をみつける。 配列の大きさが同しなので、要素ごとの連結をおこな 154 155 156 157 158 159 160 161 StrEdArray ret (from—index , to—index) ; for (int i from_index ; i く =to_index ; 土十十 ) ret. array [Trans1ateIndex (i) ] array [Trans1ateIndex (i) ] + r. array [Trans1ateIndex(i)] ; return ret ; 194 195 196 197 198 199 200 for (int 」 i + 1 ; j く = to—index smallest—index = コ ; ret . array[Trans1ateIndex(j)] ) (smallest—index)] > if (ret . array [Trans1ateIndex 地」、の要素を適切な位置に移動する。 演算子 + = は、オペランドか整数または浮重ル」、点数の 場合、 = および + の関係と一貫性をもつように定義され る。したがって、この文字列配列の場合、 A + = B は A = A + B と面である。 162 StrEdArray & StrEdArray : : operator + = 201 202 203 204 205 206 207 20 8 if (smallest—index ! = i) { StrEd copy (ret . array [smallest—index] ) ; ret. array[smallest—index] = ret . array[i] ; ret . array [i] COPY ; 完了。ソートされた酉改」を返す。 163 164 165 166 167 168 169 170 171 (const StrEdArray (r) { *this 十て ; StrEdArray ret for (int i = from—index ; i く =to—index ; i + 十 ) { StrEd x(ret. array [Trans1ateIndex(i) ] ) ; return *this ; array[Trans1ateIndex(i)] = x; 209 210 ret ; 文字列と酉改姥加算するための或演算子 + ( オペラン ドの順序が逆になっているだけで、働きは文字列酉改」 + 文 字列の演算子とよく似ている ) 。 211 StrEdArray operator + (const StrEd &s , 文字列配列と文字列を加算する。文字列を酉例にしてお こよっ。 172 StrEdArray StrEdArray : : operator + 212 213 214 const StrEdArray (a) { return StrEdArray (). LowerIndex ( ) , a ・ UpperIndex(), s) + a; 173 174 175 176 } (const StrEd (r) const { return (*this) 十 StrEdArray(from—index , to—index, 215 } 寅算子は、ストリームを出力する。 216 ostream &operator くく (ostream &s, 遡頂の配列を返す。単純に戻り値の酉改」を石御呆し、要素 84 217 218 const StrEdArray (A) { StrEdArray B (A) ; UNIX MAGAZINE 1992.5

5. UNIX MAGAZINE 1992年5月号

酉改腰素を出力する。 254 連載②オプジェクト指向の世界 StrEdArray R3 ( 0 , 3 ) ; 219 220 221 222 223 for (int i = B. LowerIndex() ; i く =B. UpperIndex ( ) ; i + + ) S くく i くく " ・ return S ; 次のプライベート・メンバー関数は、インデックスの検 224 int StrEdArray : : TransIateIndex 査と変換をおこなう。 cout くく " \ n4. R を代入したを出力 \ Ⅱ” R3 に関する情報を出力する。 cout くく” \ Ⅱ 5. R3 に関する情報を出力 \ n " cout くく "\tR3 さ " くく R3. Length() cout くく "\t 下ド艮インデックス : ” くく R3. LowerIndex() くく "\n" cout くく " \ t 艮インデックス : " くく R3. UpperIndex() くく "\n" 263 262 261 260 259 258 257 256 255 出力する。 すべての配列要素を出力し、そのなかのすべての文字を 225 226 227 228 229 230 231 232 233 234 235 236 237 238 (const int index) const{ if (index く from_index) { cout くく "StrEdArray : : Trans1ateIndex (const int index) , index = cout くく index くく く from—index , exit\n' exit(l); if (index > to_index) { cout くく "StrEdArray : : TransIateIndex (const int index) , index exit(l) ; > to—index , exit\n" cout くく index くく " 264 265 266 267 268 cout くく " \ Ⅱ 6. R3 配列素 ( および各要素の文字 ) を出力 \ n " ・ for (i = R. LowerIndex() ; i く =R. UpperIndex() ; 土 + + ) { cout くく くく i くく” 最後に、 [ 0 to—index ー from—index] の危囲 に変換されたインデックスを返す。 239 240 return index ー from_index ; 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 for (int j=O; j く (R[i]) . Length()-I; j + + ) cout くく " くく j くく くく (R[i])[j] くく " if (R[i] . Length() > 0 ) cout くく "char " くく R[i] . Length()—1 くく " くく (R[i] ) CR[i] . Length()-1] 新たに配列 Radd を作り、出力する。 cout くく” \ Ⅱ 7. 連想探索を試す まず Radd を作り、それを出力する \ Ⅱ " ・ StrEdArray Radd(O , 3 ) ; Radd [ 0 ] 主プログラム こからが、主フ。ログラムである。 241 int 242 main(int argc , char *argv ロ ) 243 { 最初の配列を確立する。 Radd [ 1 ] Radd [ 2 ] "abc—2" ・ Radd [ 3 ] cout くく Radd; その配列中の ( 既存の ) 文字列 abc-l を捜す。 244 245 cout くく” 1 . 初己列 R を出力 \ Ⅱ " StrEdArray R(), 3 , " ー 酉改」にさまざまな要素を設定する。 246 247 248 249 for (int i = 0 ; i く = 3 ; i 十 + ) cout くく " \ n2. 言聢後己列 R を出力 \ n ” cout くく R; 286 287 288 289 290 291 292 293 cout くく " \ Ⅱ 8. 文字列 abc-l は酉リ Radd" ・ if (Radd["abc—1"] (Radd. LowerIndex ( ) cout くく " には存在しない " ・ else cout くく " に存在する。位置は くく Radd["abc—1"] ; cout くく その配列には存在していない文字列 xxyy を捜す。 配列のコピー R2 を作る。 250 StrEdArray R2 (R) ; 次に R2 を変更して出力し、 R と R2 が別のものであ ることを示す。 294 295 296 297 298 299 300 301 cout くく "\n9. 文字列 xxyy は酉リ Radd" ・ if (Radd ["xxyy"] (Radd. LowerIndex ( ) cout くく " には存在しない " ・ else cout くく " に存在する。位置は 251 252 253 R2 [ 2 ] 'Something else" ・ cout くく " \ n3. R2 を出力 R とほとんと祠じ \ Ⅱ”くく R2; くく Radd["xxyy"] ; cout くく " \ Ⅱ " StrEdArray オプジェクトの重加轄リ当てを見る。 代入演算子を試す。 UNIX MAGAZINE 1992.5 30 2 StrEdArray *Rp = new StrEdArray (R2) ; 85