Ist reinterpreting ein Mitglied Funktionszeiger eine ‚gute Idee‘?
-
21-09-2019 - |
Frage
Ich habe einen Worker-Thread, der eine Liste von ‚Thema Aktionen‘ hält, und arbeitet durch sie als wenn.
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;
};
Es ist normalerweise wie dies
genanntmyActionThread->addAction(
new ThreadAction<TheirClass>(this, &TheirClass::enable)
);
Welche fein gearbeitet, bis
void TheirClass::enable()
wurde geändert
bool TheirClass::enable()
Leider können wir es nicht wieder ändern zurück, weil andere Sachen das neue Format benötigt, (und Überlastungen kann unterscheiden sich nicht von Rückgabetyp allein).
Ich habe versucht,
myActionThread->addAction(
new ThreadAction<TheirClass>(this,
reinterpret_cast<void(TheirClass::*)>(&TheirClass::enable)
)
);
Welche gut funktionieren scheint, aber ich bin nicht sicher, dass ein Funktionszeiger wie folgt neu zu interpretieren ‚definiert‘ Verhalten ist, kann jemand bitte raten?
Lösung
Dies ist definitiv nicht unterstützt Verhalten und kann möglicherweise Ursache Ihr Programm zum Absturz bringen.
Grundsätzlich müssen Sie einen Wrapper für TheirClass::enable()
machen, die den richtigen Rückgabetyp haben. Ein einfacher Einzeiler genügt:
public:
void enableWrapper() { enable(); };
Dann rufen:
myActionThread->addAction(
new ThreadAction<TheirClass>(this, &TheirClass::enableWrapper)
);
Wenn Sie nicht TheirClass
direkt ändern können, dann erstellen Sie eine einfache Unterklasse oder Helfer-Klasse, die Geräte der Wrapper.
Andere Tipps
Err, von dem, was ich verstanden habe, du bist Gießen von einem Verfahren, dass die Rendite eines bool
ein Verfahren, dass die Renditen void
?
Dies kann gefährlich sein, abhängig von der anrufenden / Rückkehr Konvention im Einsatz. Sie könnten vergessen, den Rückgabewert Pop -. Oder den Wert eines Registers mit dem Rückgabewert außer Kraft setzen
Keine gute Idee. Erwägen Sie einen zusätzlichen Template-Parameter für Rückgabetyp:
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;
};
Dies ist eine Anwendung von Rückkehr nichtig .
ich, dass im Allgemeinen finden, wenn die Frage nach der Form ist: „Ist _______ eine gute Idee?“ die Antwort ist fast immer „NEIN!“
Das ist wohl wahr, ohne Kontext.