さらに base を継承した baseXYZ を作成し、
#include <boost/any.hpp>
std::map<int, boost::any> g_any;
void test()
{
baseXY xy;
baseXYZ xyz;
g_any[10] = xy;
g_any[12] = xyz;
for(std::map<int, boost::any >::iterator it = g_any.begin();
it != g_any.end(); it++)
{
SendData(&boost::any_cast< *** >(it->second)); //エラー
}
}
*** の部分をどう書いていいのかわかりません。どなたかご教授ください。
よろしくお願いします。
って、これじゃ仮想にならない
std::map<int, boost::any*> g_any;
baseXY* p = new baseXY;
g_any[10] = p; //要キャスト
とか.
>って、これじゃ仮想にならない
>std::map<int, boost::any*> g_any;
仮想?上の例なら std::map< int, boost::any > でいいような気が?
例)
boost::any a;
a = 10;
std::cout << boost::any_cast< int >( a );
>って、これじゃ仮想にならない
>std::map<int, boost::any*> g_any;
ひょっとして
class Base {};
class BaseXY : public Base {};
class BaseXYZ : public Base {};
std::map< int, Base* >
ってことですか?
ttp://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200512/05120021.txt
の通り、baseはtemplateで
std::map<int, base<> >
がどう書いていいか良くわからないんですよね。申し訳ないです。
前スレの件と前後するのでどう説明していいかも微妙なんですが
あるスレッド1は メッセージA でTYPE_XYのデータを受け取りたい。また
あるスレッド2は メッセージA でTYPE_XYZのデータを受け取りたい。さらに
スレッド3~が存在する場合もありそのときは メッセージA でTYPE_XYZθ を受け取りた
い。
各スレッドへのデータ送信は同時に行われる事が多い。
という条件で
void メッセージAを各スレッドに送る()
{
for(......)
{
send(送り先、メッセージA、データ);
}
}
こういう関数を実現したいんです。
このための手段としてtemplateと仮想関数の実装をしていたのですが
慣れないものでつまずきっぱなし(TT
> std::map<int, base<***> >
template<class T>
std::map<int, base<T>* >
とか?
ふと思いました。
用は baseXY or baseXYZ クラスでそれぞれ異なる構造体を扱いたいんですよね?
なら base クラスを template にする必要はない様な気がします。
むしろ構造体のほうを継承してやる。
こんなかんじでいいのかな?
struct TYPE
{
int type_;
};
struct TYPE_XY : public TYPE
{
int x_;
int y_;
};
struct TYPE_XYZ : public TYPE
{
int x_;
int y_;
int z_;
};
class base
{
public:
base( TYPE* type ) : type_( type ) {}
TYPE* Get() { return type_; }
private:
TYPE* type_;
};
int main()
{
TYPE_XY type_xy;
TYPE_XYZ type_xyz;
type_xy.x_ = type_xy.y_ = 1;
type_xyz.x_ = type_xyz.y_ = type_xyz.z_ = 2;
std::map< int, base* > type_map;
type_map[0] = new base( &type_xy );
type_map[1] = new base( &type_xyz );
std::cout << static_cast< TYPE_XY* >( type_map[0]->Get() )->x_;
std::cout << static_cast< TYPE_XYZ* >( type_map[1]->Get() )->z_;
}
>RAPTさん
回答ありがとうございます。でも
template<class T>
map<int, base<T> > data; って、コンパイル通んないっす。。
>DDさん
異なる構造体を扱いたいのは間違いないのですが、明示的なキャストを避けて使えるのもが
欲しいかなと(^^;
もうちょっと研究してみます。
もし何かいい方法ご存知でしたらアドバイスお願いします。
>明示的なキャストを避けて使えるのもが欲しいかなと(^^;
継承と仮想関数は、同じ型として扱える場合に効果があります。
下記のようなものではだめでしょうか?
class Base {
void *p;
public:
virtual size_t GetSize() const =0;
void *GetDataPtr() const{return p;}
Base(void *pp):p(pp){}
};
class BaseXY : public Base {
TYPE_XY data;
public:
BaseXY():Base(&data){}
size_t GetSize() const{return sizeof(data);}
};
補足
GetDataPtrも仮想にすれば、メンバのpは不要になります。
> map<int, base<T> > data; って、コンパイル通んないっす。。
map<int, base<T>* >
と書いたのですが。(第二引数の型はポインタ型)
ちなみに、ポインタにしてもしなくてもコンパイルは通ったのですが、
一体ドコに上記のコードを書いたのでしょうか。
返信遅くなってしまってすみません。
>REEさん
class base {
public:
virtual size_t size() const =0;
virtual void* Get() = 0;
base(){}
~base(){}
};
class baseXY : public base {
TYPE_XY* data;
public:
baseXY(TYPE_XY* rhs){ data = rhs;}
~baseXY(){ delete data;} // new されることを想定
virtual size_t size()const {return sizeof(*data);}
virtual void* Get(){return data;}
};
こういうことでしょうか?
>RAPTさん
template <class T>
std::map<int, base<T>* > data;
グローバルです。
error C2262: 'data' : 壊せません。
error C2133: 'data' : サイズが不明です。
のように怒られてしまいます。
template と継承派生は generics を、逆というか横というか、とにかく、
違う方向から追求しているものなので、自分が今設計しているものにより適合するのが
どちらであるかをよく考えた上で選択する必要があります。
とりあえずこんなのを作ってみました。参考になれば幸い。
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
struct base {
virtual ~base() {}
virtual void do_something()=0;
};
struct x : public base {
virtual void do_something() { std::cout << x << std::endl; }
};
struct y : public base {
virtual void do_something() { std::cout << y << std::endl; }
};
typedef std::vector<boost::shared_ptr<base> > myvec;
int main() {
myvec v;
boost::shared_ptr<base> xx(new x); v.push_back(xx);
boost::shared_ptr<base> yy(new y); v.push_back(yy);
for (myvec::iterator it=v.begin(); it!=v.end(); ++it) {
(*it)->do_something();
}
return 0;
}
>template と継承派生は generics を、逆というか横というか、とにかく、
>違う方向から追求しているものなので、自分が今設計しているものにより適合するのが
>どちらであるかをよく考えた上で選択する必要があります。
派生先に(templateだとして)
T Get() = 0; //今回はこの部分を設計に関わる事項だと思っています
T& GetRef() = 0; //同上
size_t size()const = 0;
などを実装させるような仕組みにしつつ、
その派生クラスa, b 同士は横のつながりがあって std::vectorやmapでひと括りに
出来るものを目指してみたのですが・・・。
いろいろ助言を聞いてやってみたのですが明示的な型変換で躓いてしまいます。
そんな我侭なものは作れないのでしょうか??
ダメならダメで仕方が無いとは思っていますが
引き続き助言お願いします m(_ _)m
baseXY と baseXYZは、共にbaseとして扱えるため、ひと括りに処理できます。
しかし、TYPE_XYとTYPE_XYZには、全く関連がないため、ひと括りに処理できません。
ひと括りに扱うには共通点が必要で、その共通部分だけをまとめて処理できます。