標準コンテナを基底クラスに使ってもいいんですか?

[戻る]
kyu 2003/12/04(木) 16:31:14
std::vectorとかstd::mapとかを継承して新しいクラスを
作っていいのでしょうか?

たとえば、
class hoge : public std::map<int,std::string>
{
・・・
};

とか。

std::vectorはデストラクタがvirtualじゃないようなので
心配になりました。

επιστημη [E-Mail] [HomePage] 2003/12/04(木) 16:33:12
やってもかまいません。ただし、

> std::vectorはデストラクタがvirtualじゃないようなので
> 心配になりました。

こんな心配をしなければならないような作り方/使い方さえしなければ。

kyu 2003/12/04(木) 16:44:56
>こんな心配をしなければならないような作り方/使い方さえしなければ。

どういう所に注意して作成したらいいのか、ポイントを
教えていただけたら、とてもうれしいです。

私はこんなのを作成しようと思ってました。
エラー番号からエラー文字列を返すmap。
class ErrorMap : private std::map<int, std::string>
{
private:
  ErrorMap();
public
  static std::string Message( int errNo );
};

ErrorMap::ErrorMap()
{
 insert( std::pair< ・・・
 insert( ・・・
 ・・・
}

std::string ErrorMap::Message( int errNo )
{
 static ErrorMap emap;
 emap.find( ・・・ 

 return ・・・
}

επιστημη [E-Mail] [HomePage] 2003/12/04(木) 16:53:26
std::map<int,std::tring> を ErrorMap のメンバにしちまった方が
悩みがなくて幸せではないかしら。

class ErrorMap {
  std::map<int,std::string> theMap;

public:

  ErrorMap() {
    theMap[0] = "だめ";
    theMap[1] = "むり";
    ...
  }

  std::string getMessage(int code) const {
    std::map<int,std::string>::const_iterator iter = theMap.find(code);
    assert( iter != theMap.end() );
    return iter->second;
  }

};

kyu 2003/12/04(木) 17:11:21
> std::map<int,std::tring> を ErrorMap のメンバにしちまった方が

なるほど!ありがとうございます。


> やってもかまいません。ただし

やっても大丈夫な使い方が、思い浮かばないのです・・・
やっぱりよくないってことですよね?

基底クラスのデストラクタが呼ばれない可能性があるってことは
例えば、基底のvecotorの値が開放されない可能性が出てくる
ってことな気がしますし、つまりはデータを入れるとまずいってことは
継承する意味がないような気がしますし。

ぅぅ。わからないぃ。

επιστημη [E-Mail] [HomePage] 2003/12/04(木) 17:15:06
> 基底クラスのデストラクタが呼ばれない可能性があるってことは

ちがいます。
呼ばれない可能性があるのは'派生クラス'のデストラクタ。

std::map<int,std::string>* p = new ErrorMap();
delete p; // ~ErrorMap() は呼ばれない。

kyu 2003/12/04(木) 17:31:02
[[解決]]
> 呼ばれない可能性があるのは'派生クラス'のデストラクタ。

はっ。確認しました。
私、どうも勘違いしてたようです。

ErrorMap* p = new ErrorMap();
delete p; // 両方呼ばれた

std::map<int,std::string>* p = new ErrorMap();
delete p; // ~ErrorMap() は呼ばれない。

派生クラスでの、メンバ変数がらみが、まずい。と。

ありがとうございました。ー> επιστημηさん

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