ぎょーむ日誌 2000-08-17
2000 年 08 月 17 日 (木)
- 0700 起床.
くもり.
- あ,
飯を炊いてなかった.
うわー,
電灯つけっぱなしの
冷蔵庫のドア開きっぱなし.
おそらく,
昨晩は気絶するようにして
いきなり寝ちまったんだろうなあ.
- 飯を炊いて,朝飯・弁当の準備.
シャワー.
朝飯.
- 0813 自宅発.
曇り.
やや涼しいか?
0829 東京モノレイル流通センター発.
外気温 25 ℃.
やけに低いなあ.
東京にしては.
浜松町駅でまた一ヵ月有効の定期券買う.
10300 円.
0850 研究所着.
- いまごろになって,
昨日と一昨日のぎょーむ日誌書く.
とほほ.
- ロシア原子力潜水艦いまだ救助ならず.
よーやく NATO に救援要請.
遅いんだよ,
莫迦.
あ,
しかしアメリカなんかの支援申し出は
まだ断り続けているな.
見栄なのか.
どうせ間に合わないとあきらめたか.
- 悲しむべきことに
我々の世界には国際救助隊
<サンダーバード>
は存在できないようだ.
工学技術的な問題点だけでなく,
そういう組織が活動できる
社会情勢ではない,
というか.
- 先日「蒸発」したと思っていたメイルが
続々と
研究所のメイルサーヴァー
(MTA は sendmail)
から「届きませんでした」
お知らせとともに送り返されて来た.
いったい,
どういう設定 ?
- さーてと,
昨日 ce-ml 上でいろいろとやりとりされた,
C++ の継承と STL の関係である.
メイルのやりとりの経過は
……
私が C++ の仕様について
まるで勉強不足なことを次々と書き,
竹中さんがそれを片っ端から訂正してくださる,
というスタイルで進行したのであった.
- えーと,
まずは問題点から.
たとえば,
基底クラス Tree と その派生クラス Acer を定義したとする.
// 基底クラス Tree class Tree { protected:
string name;
public:
Tree( void ): name( "tree" ) { ; }
void InputName( const string& newname );
const string& Name( void ) const { return name; }
};
// 派生クラス Acer (->Tree) class Acer : public Tree { public:
Acer( void ) { InputName( "acer" ); }
void InputName( const string& newname );
const string& Name( void ) const { return name; }
};
// Tree と Acer のメンバー関数 InputName void Tree::InputName( const string& newname ) { name = newname + " (changed in Tree object)"
}
void Acer::InputName( const string& newname ) { name = newname + " (changed in Acer object)"
}
- で,
私が先週「うまくできた」とか言ってたのは,
例えば次のような操作である.
Acer acer1; // Acer である acer1 を宣言 vector<Tree> forest; // Tree の vector を forest として宣言 forest.push_back( acer1 ); // acer1 を forest につっこむ
- これでエラーは出ないし,
forest の最初の要素に対して
「あなたの Name() は?」
とお尋ねすると
(``tree'' ではなく)
``acer''
というふうに回答してくれる.
- そこで私は勘違いして
「vector<Tree> である forest には, Tree クラスのオブジェクトだけでなく, Tree の派生クラス Acer のオブジェクトである acer1 みたいなのも放り混むことができるんだ」
と錯覚したわけだ.
- ところが,
これはうまくいってるようでいて,
そうはなっていないのである.
私は Acer クラスのオブジェクトを入れたつもりに なっているんだけど,
forest の要素はあくまでも Tree のままなのである.
- たとえば,
forest の要素に対して InputName( "kaede" ) としてみよう.
その後に
もう一度
「あなたの Name() は?」
とお尋ねすると ``kaede ( changed in Tree object)'' となる.
つまり Acer ではなく Tree のオブジェクトが forest に格納されているのである.
- なぜ,
そうなるのか?
というと,
C++ と STL の仕様では,
forest.push_back( acer1 );
というふうにコンテナーを新しく作ろうとした場合,
自動的に以下のように,
forest.push_back( Tree( acer1 ) );
Acer クラスの acer1 が, Acer の基底クラスである Tree クラスに変換される (そのときに name のデーターである ``acer'' が
引き継がれる).
そうして生成された無名の一時的な Tree オブジェクトが コピーコンストラクターによって
コンテナーの部品である Tree オブジェクトに複製される, という過程を経るのである.
したがって,
forest に Acer を突っ込むことはできない.
- 「えー,
でも forest には色んな種類の樹木を
入れたいじゃないですかぁ」
という要求は当然ある.
これに対して竹中さんから教えていただいた
解決策は以下のようなものである.
Acer acer1; // Acer である acer1 を宣言 vector<Tree*> forest; // Tree* の vector を forest として宣言 forest.push_back( &acer1 ); // acer1 のポインターを forest につっこむ
- つまり forest を Tree クラスのオブジェクトのポインターである Tree* の vector とすればよい,
というシンプルなものだ.
基底クラスオブジェクトへのポインターは
派生クラスオブジェクトへのポインターとしても使ってよい,
という C++ の仕様が定められており,
それをうまく利用した解決策なのである.
C++ の FAQ の継承に関する章
など参照してください.
- これによって
Acer などのように Tree から派生したクラスのオブジェクトを 要素とする STL なデーター構造 (vector など) を使えるようになる.
- ただし
コンテナーを削除するときには,
(当然のことながら)
まずは
そのポインターが示すオブジェクトを delete しなければならない.
- いやはや,
やっぱり C++ って
きちんと使うのはたいへんな言語です.
って,
これぐらいのコトでネをあげていては,
この先おもいやられるなあ.
- お昼を食べようと箸箱を開くと,
中はからっぽ.
あわてず騒がず
引出しから予備の割箸を取り出す.
自分のうかつさを自覚していればこそ,
対策もたてられるのである.
といばれるほどのことでもないな.
- 弁当食いながら,
ネット上のニュース読む.
xDSL 接続が年内に東京 23 区全域に拡大,
か.
東京めたりっく
.
常時接続はどっちがいいんだろうね.
高速だけどまだまだ普及してない ADSL か.
なんか腐れてるけど実績のある ISDN か.
- 歩いて 2 分ほどのところにある ATM に
入金にいく.
5 分ほど行列.
帰って来てネットからアクセスしてみると,
すでにデーター更新されてる
……
これは当り前か.
- Gamete シミュレイターの仕様再検討.
中断していた作業を進める.
「あたり」判定とかについては,
現段階ではいいかげんに不真面目にやるつもり
なんだが,
将来はきちんとやる,
という前提で細部を検討する.
- シーヴァンスにおられる事務の方からメイル.
学振の源泉徴収票の提出 ?
げんせんちょーしゅーひょーって何なに何 ?
と錯乱しかけたが,
落ち着きを取り戻してネット上で調べると
……
なーんだ,
学振からこちらに送ってもらえばいいんだな.
えーと,
たしか最近になって家に学振からの手紙が来ていた.
あれにメイルアドレスとか書いてあったような気がする.
- 沈んだままの <クルスク> の乗員って,
とっくに全員死んでるんじゃないの,
との CNN 報道.
バレンツ海に展開していたアメリカ原潜が情報源らしい.
何日も前から壁を叩く音なんか聞こえちゃいないよ,
とのこと.
うーん,
どうなんだろうね.
しかし,
この報道でもっとも驚いたのは,
なんとまあいまだに
ロシア海軍の演習のたびに,
こっそりと
それにつき合ってるアメリカ海軍の律義ぶりである.
貞節というか
ストーカーというか.
- 1750 研究所発.
1806 東京モノレイル浜松町発.
1846 帰宅.
- 源泉徴収票なるものは,
私としては珍しいことに,
捨てずにちゃんと残されていた.
- なんか眠くて仕事が進まん.
- 今日の食卓
- 朝 (0750):
昨晩の味噌汁の残り.
タマネギ・ナス・ピーマン・ショウガの
炒めもの.
- 昼 (1220):
弁当.
タマネギ・ナス・ピーマン・ショウガの
炒めもの.
- 晩 (1900):
朝の残り.