仮想関数 と 多重継承の使い方

[戻る]
いとう 2004/01/07(水) 08:02:26
お世話になっております。
現在 template と 仮想関数を 使いいろいろ試しているのですが、
つまづいてしまいましたので質問させていただきます。

typedef class classAPPOBJECTBASE
{
public :
virtual int Destroy() =0;
virtual int Render() =0;

}APPOBJECTBASE;

template<typename T> class classAPPOBJECT: public classAPPOBJECTBASE{

public:
virtual int Create(T *t) =0;
};

class classAPPA: public classAPPOBJECT<int>{

public:
int int Create(int a ){ return 0};
int Destroy(){ return 0};
int Render(){ return 0};
};
class classAPPB: public classAPPOBJECT<byte>{

public:
int int Create(byte a ){ return 0};
int Destroy(){ return 0};
int Render(){ return 0};
};


classAPPA や classAPPB を一つの変数で保持できるように
vector<classAPPOBJECTBASE *> vecObject;
を用意し下記の関数を通して登録しています。

template<typename T , typename U >int MakeObject(T** t, U *u)
{
T *p = new T;

p->Create(u);

this->vecObject.push_back(p);

//作成されたオブジェクトのポインタ
*t = p;
return 0;
}

登録した後
this->vecObject からclassAPPA やclassAPPBのポインタを
取得する方法はないのでしょうか?
明示的にキャストすれば良いのかなとおもったのですが別の
方法があるのでしたら、是非教えて頂けませんでしょうか?


それと、このようなやりかたをやっている場合

class classTEST
{
int test;
int ttt;
};
class classAPPB: public classAPPOBJECT<byte>, public classTEST{

public:
int int Create(byte a ){ return 0};
int Destroy(){ return 0};
int Render(){ return 0};
};
多重継承のクラスを使用することはできないのでしょうか?
(this->vecObject[]からアドレスを取得すると 確保したアドレスと違うモノになって
います。)

教えてください。よろしくおねがいします。

επιστημη [E-Mail] [HomePage] 2004/01/07(水) 09:51:23
> this->vecObject からclassAPPA やclassAPPBのポインタを
> 取得する方法はないのでしょうか?

質問の意図が掴めません。 
vecObjectには classAPPA*, classAPPB*が混在しているわけで、
そのなかから一方を取り出したい、ということでしょうか?

そういうことなら dynamic_cast すればいい。

> 多重継承のクラスを使用することはできないのでしょうか?
> (this->vecObject[]からアドレスを取得すると 確保したアドレスと違うモノになって
> います。)

多重継承しているならあり得ることです。
'使用することができない'とは?

いとう 2004/01/08(木) 00:30:22
>質問の意図が掴めません。 
>vecObjectには classAPPA*, classAPPB*が混在しているわけで、
>そのなかから一方を取り出したい、ということでしょうか?

>そういうことなら dynamic_cast すればいい。
  
 vecObjectのn番目の情報を取得したいときに 
 classAPPAかclassAPPBかわからないので、どうやってキャストすれば良いか
 わからないということです。 
 dynamic_castを調べてみます。
 
>多重継承しているならあり得ることです。
>'使用することができない'とは?

  アドレスが違っているので、delete をやった場合
 正しく解放できないようが気がするのです。
 

επιστημη [E-Mail] [HomePage] 2004/01/08(木) 01:16:23
>>多重継承しているならあり得ることです。
>>'使用することができない'とは?
>
>  アドレスが違っているので、delete をやった場合
> 正しく解放できないようが気がするのです。
 
#include <iostream>
#include <new>
#include <cstdlib>

void* operator new(size_t n) {
  void* result = malloc(n);
  std::cout << "malloc(" << n << ") -> " << result << std::endl;
  return result;
}

void operator delete(void* p) {
  std::cout << "delete(" << p << ")" << std::endl;
  free(p);
}

class father {
public:
  father() { std::cout << "father\n"; }
  virtual ~father() { std::cout << "~father\n"; }
};

class mother {
public:
  mother() { std::cout << "mother\n"; }
  virtual ~mother() { std::cout << "~mother\n"; }
};

class child : public father, public mother {
public:
  child() { std::cout << "child\n"; }
  virtual ~child() { std::cout << "~child\n"; }
};

int main() {
  father* f = new child();
  std::cout << "father: " << static_cast<void*>(f) << std::endl;
  delete f;
  std::cout << std::endl;
  mother* m = new child();
  std::cout << "mother: " << static_cast<void*>(m) << std::endl;
  delete m;
  return 0;
}

…安心しましたか?

いとう 2004/01/09(金) 08:29:07
[[解決]]
両方納得しました。
dynamic_castのほうは初めエラーがでてしまい、上手くいかなかったのですが
ソフトのほうで設定したら無事に変換できました。

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

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