メンバー関数ポインターを再解釈することは「良いアイデア」ですか?
-
21-09-2019 - |
質問
「スレッドアクション」のリストを保持し、それらを when として処理するワーカースレッドがあります。
template <class T> class ThreadAction
{
public:
typedef void (T::*action)();
ThreadAction(T* t, action f) :
func(f),obj(t) {}
void operator()() { (obj->*func)(); }
void (T::*func)();
T* obj;
};
通常はこのように呼ばれます
myActionThread->addAction(
new ThreadAction<TheirClass>(this, &TheirClass::enable)
);
それまではうまくいきました
void TheirClass::enable()
に変更されました
bool TheirClass::enable()
残念ながら、他のものには新しい形式が必要なため、これを再度変更することはできません (また、オーバーロードは戻り値の型だけによって異なることはできません)。
試してみました
myActionThread->addAction(
new ThreadAction<TheirClass>(this,
reinterpret_cast<void(TheirClass::*)>(&TheirClass::enable)
)
);
これは問題なく動作しているように見えますが、このように関数ポインターを再解釈することが「定義された」動作であるかどうかわかりません。誰かアドバイスしてください。
解決
これは間違いであるのの動作をサポートし、することができ、潜在的にクラッシュするプログラム原因ではない。
基本的に、あなたは適切な戻り値の型を持っていますTheirClass::enable()
のラッパーを作成する必要があります。シンプルなワンライナーで十分です。
public:
void enableWrapper() { enable(); };
次に呼び出します:
myActionThread->addAction(
new ThreadAction<TheirClass>(this, &TheirClass::enableWrapper)
);
あなたが直接TheirClass
を変更できない場合は、、その後、実装ラッパーます。
という単純なサブクラスまたはヘルパークラスを作成します他のヒント
えー、私が理解したところによると、あなたは を返すメソッドからキャストしているようです。 bool
を返すメソッドに void
?
これは、使用されている呼び出し/戻り規則によっては危険である可能性があります。あなた かもしれない 戻り値をポップするのを忘れるか、レジスタの値を戻り値でオーバーライドします。
はない良いアイデア。戻り値の型のための追加のテンプレートパラメータを追加することを検討します:
template <class T, typename RetType> class ThreadAction
{
public:
typedef RetType (T::*action)();
ThreadAction(T* t, action f) :
func(f),obj(t) {}
RetType operator()() { return (obj->*func)(); }
RetType (T::*func)();
T* obj;
};
これは
私は一般質問の形式である場合いることを見つける「_______良いアイデアですか?」答えはほとんど常に "NO!" です。
このコンテキストなしで、おそらく本当です。
所属していません StackOverflow