/任意のC++ 17、ベースクラスから「doSometing」関数のパラメータを導出検討し、それらへの動的なキャストを行います正しいクラスオブジェクト。この場合、実行時に有効なポインタがあることを確認できます。
class param{
public:
virtual ~param(){};
};
template <typename T>
struct specificParam:param{
specificParam(T p):param(p){}
T param;
};
class Foo
{
public:
virtual void doSomething(param* data) = 0;
};
template <typename T>
class Bar : public Foo
{
public:
virtual void doSomething(param* data){
specificParam<T> *p = dynamic_cast<specificParam<T> *>(data);
if (p != nullptr){
std::cout<<"Bar got:" << p->param << "\n";
}
else {
std::cout<<"Bar: parameter type error.\n";
}
}
};
int main(){
Bar<char> obj1;
Bar<int> obj2;
Bar<float> obj3;
specificParam<char> t1('a');
specificParam<int> t2(1);
specificParam<float> t3(2.2);
obj1.doSomething(&t1); //Bar got:a
obj2.doSomething(&t2); //Bar got:1
obj3.doSomething(&t3); //Bar got:2.2
// trying to access int object with float parameter
obj2.doSomething(&t3); //Bar: parameter type error.
}
最も簡単な(しかし安全ではない!)の方法は、Type-消去が唯一の可能性ではありませんvoid *型のポインタ+静的キャスト
class Foo
{
public:
virtual void doSomething(void* data) = 0;
};
template <typename T>
class Bar:public Foo
{
public:
virtual void doSomething(void* data){
T* pData = static_cast<T*>(data);
std::cout<<"Bar1 got:" << *pData << "\n";
}
};
int main(){
Bar<char> obj1;
Bar<int> obj2;
Bar<float> obj3;
char c = 'a';
int i = 1;
float f = 2.2;
obj1.doSomething(&c); // Bar1 got:a
obj2.doSomething(&i); // Bar1 got:1
obj3.doSomething(&f); // Bar1 got:2.2
//obj2.doSomething(&c); // Very bad!!!
}
出典
2017-09-07 08:11:57
Nir
は、あなたがより具体的に説明してくださいすることができますがあなたはVisitorパターンを使用して興味がある可能性があり
?どのように関数内のデータを使用しますか?データのタイプの要件は何ですか?例えば。ご存じのクラスがいくつかありますか、または特定のメソッドなどを持つクラスを受け入れる予定ですか? – bolov
あなたの質問はちょっと狭められる必要があります。タイプの範囲を知っていますか?自動的に推論されますか?最も単純な答えは "void *を使う"でしょう。ストーリーテラーの方が良い答えかもしれません。それはあなたのユースケースに左右されます。 –
'doSomething'をキャスティングすることなく同じ結果を達成する可能性があるのなら、私は不思議で、答えを見ています。 'doSomething'をテンプレートにすることなく型を何らかの方法でカプセル化し、' decltype'、すなわち仮想ファクトリメソッドの種類を取り出すことのようなもの... – perencia