どっちのマップクラス?

[戻る]
シャノン 2004/01/18(日) 12:59:52
現在、「整数をキーとするポインタのマップ」を必要としています。
今は CMap< DWORD, DWORD &, CHoge *, CHoge *& > としていますが、ポインタを格納す
るには CTypedPtrMap を使うべきなのか?と悩んでいます。
とりあえず、現状で問題なく動作しますし、このマップの要素をシリアル化する必要が
あるのです。
現在は SerializeElements をオーバーライドして正常にシリアル化/逆シリアル化も成
功しているのですが、すると、シリアル化できないとされている CTypedPtrMap は 
CMap に比べてどのようなメリットがあるのか?ということがいまいちわからないので
す。
要素の型にポインタを使う CMap クラスと CTypedPtrMap クラスの違いを、簡単に教え
ていただけないでしょうか。よろしくお願いします。

環境は Win98 SE、VC++ 6.0 です。

シャノン 2004/01/18(日) 13:10:26
すいません、ちょっと追記です

>シリアル化できないとされている CTypedPtrMap は
ベースの型によってはシリアル化できる場合もあるのですね。ですが、ベースには 
CMapWordToPtr(でいいのかな?)を使うことになると思いますので、そのままではシリ
アル化できない、と解釈してください。

>このマップの要素をシリアル化する必要があるのです
CTypedPtrMap を継承して Serialize メソッドをオーバーライドしてやれば可能か?と
思うのですが(試してはいませんが)、「ポインタを格納する」という理由だけでそこ
までして CTypedPtrMap を使うべきなのか、ポインタを型とする CMap で十分なのかを
教えていただけないでしょうか。

てつや 2004/01/18(日) 13:13:24
タイプセーフかどうかだと思います。
MSDNに詳しく説明がのっているので一読される事をお勧めします。

http://www.microsoft.com/japan/developer/library/vccore/_core_collections_topics
.htm

ここに各コレクションの比較があります
http://www.microsoft.com/japan/developer/library/vccore/_core_collections.3a_.ch
oosing_a_collection_class.htm

シャノン 2004/01/18(日) 15:47:53
てつやさん、早速のレスありがとうございます。

タイプセーフってのは、格納できる値の型が保障されているってことですよね。
例えば、CMapWordToPtr は WORD をキーとする void * のマップ、つまり値にはどんな
型のポインタも格納できてしまうからタイプセーフではない。対して CTypedPtrMap< 
CMapWordToPtr, WORD, CHoge * > は値の型が CHoge * に限定されているからタイプセ
ーフである。
この解釈が間違っておりましたらご指摘ください。
以下、この解釈が合っていると仮定して話を進めさせていただきます(自信はありませ
んが)。

しかし、CMap< WORD, WORD &, CHoge *, CHoge *& > でも、格納できる値の型は CHoge 
* に限定されている=タイプセーフなのではないでしょうか?
CTypedPtrMap はシリアライズできないというのも、ポインタをビット単位でシリアライ
ズしても意味がないためであって、Serialize メソッドを適切にオーバーライドしてや
ればシリアライズ可能ではないかと思います(これから実験してみます)。

すると、CMap と CTypedPtrMap の表面的な違いがわからなくなってしまいます。
汎用性という面で見ると、どんな型でも格納できる CMap に対し、ポインタしか格納で
きない CTypedPtrMap は劣っているような印象さえ受けます。
CTypedPtrMap は汎用性を犠牲にした分、ポインタを格納することに特化して CMap より
も効率がよいなどというメリットがあるのでしょうか?
単純に考えて、CMap は格納する際に値のコピーを作りますから、CTypedPtrMap がそれ
を作らない(かもしれない)=メモリ消費が少ないというのはありえますが、タイプセ
ーフ云々とは無関係ですね。

てつや 2004/01/18(日) 17:08:26
すみません。
タイプセーフかどうかではなく、タイプセーフ付かどうかです。

マップには以下の種類のものが用意されていると思います。
CMap
CMapPtrToPtr
CMapPtrToWord
CMapStringToOb
CMapStringToPtr
CMapStringToString
CMapWordToOb
CMapWordToPtr
CTypedPtrMap

この内、CMapとCTypedPtrMapのみテンプレートクラスになっていてます。
それで、CTypedPtrMapは何者かというと、上記の非テンプレートクラスCMapPtrToPtrや
CMapPtrToWordを使う場合、シャノンさんの仰る通りタイプセーフではないので、
CTypedPtrMapを使う事によってタイプセーフになりますよっていう事です。

てつや 2004/01/18(日) 17:46:30
途中で送信してしまいました。

>CTypedPtrMap はシリアライズできないというのも、ポインタをビット単位でシリアライ
>ズしても意味がないためであって、Serialize メソッドを適切にオーバーライドしてや
>ればシリアライズ可能ではないかと思います(これから実験してみます)。
その通りだと思います。

>すると、CMap と CTypedPtrMap の表面的な違いがわからなくなってしまいます。
>汎用性という面で見ると、どんな型でも格納できる CMap に対し、ポインタしか格納で
>きない CTypedPtrMap は劣っているような印象さえ受けます。
はい、CMapさえあれば十分かと私も思います。
Microsoftさんの真意はわかりませんが、ただ、ちょっとした時にぱっと使えるように
CMapStringToPtrとか非テンプレートの関数を作ったんじゃないのかな?
そんで、これじゃなんでもかんでもポインター入れれるから、CTypedPtrMapでタイプセーフに
出来るようにしておいたのではなかろうかと私は思います。

シャノン 2004/01/18(日) 19:25:17
[[解決]]
ご丁寧にありがとうございます。

>CMapさえあれば十分かと私も思います。
結局そうなんですね。

ちなみに、最初の質問をしたところでは CMap を使おうとしていましたが、気が変わっ
たので CTypedPtrMap をいじってみようと思います。

>ちょっとした時にぱっと使えるようにCMapStringToPtrとか非テンプレートの関数を作
ったんじゃないのかな?
>そんで、これじゃなんでもかんでもポインター入れれるから、CTypedPtrMapでタイプ
セーフに出来るようにしておいたのではなかろうかと私は思います。

MSDN によれば、非テンプレートクラスは MFC 1.0 の頃からあって、MFC 3.0 でテンプ
レートクラスが追加されたんだそうですね。
CTypedPtrMap は、その頃の古いコードの移植を簡単に、かつタイプセーフにという目的
で作られたのかもしれませんね。

てつや 2004/01/18(日) 21:27:16
>MSDN によれば、非テンプレートクラスは MFC 1.0 の頃からあって、MFC 3.0 でテンプ
>レートクラスが追加されたんだそうですね。
>CTypedPtrMap は、その頃の古いコードの移植を簡単に、かつタイプセーフにという目的
>で作られたのかもしれませんね。
なるほど、了解しました。
ありがとうございます

古いスレッドには追加発言できません。