Gibt es eine Möglichkeit, in C++ zu bestimmen, ob eine Methode zur Laufzeit rein virtuell ist? In der Tat ist die Frage, ob es einen Weg gibt zu wissen, ob der Destruktor einer abgeleiteten Klasse bereits ausgeführt wurde, aber die Basisklasse noch am Leben ist.Ermitteln, ob eine Methode rein virtuell ist (C++)
Das ist mein Fall (vereinfacht):.
class BaseClass{
private:
class ThreadUtil *threadUtil;
public:
Mutex mutex;
~BaseClass(){
threadUtil->Terminate();
MutexLocker ml(mutex); // Avoid destruction during use
}
virtual Size size()=0;
};
class Derived:public BaseClass{
public:
Size size()override{return Size(100,80);}
};
class ThreadUtil{
private:
bool terminate;
BaseClass *owner;
public:
void Run(){
while(!terminate){
if (!IS_OWNER_SIZE_FN_PURE_THAT_S_THE_QUESTION){
MutexLocker ml(owner->mutex);
DoSomething(owner->size()); // Runtime error if in the dtor of BaseClass
}
}
}
};
A „rein virtuelle Funktion namens“ (wenn DoSomething aufgerufen wird, während ~ Baseclass ausgeführt wird
Terminieren des Fadenlaufzeitfehler sehr sporadisch geschieht + Locking in der abgeleiteten Klasse ist sicher, aber ich möchte es in der BaseClass tun (vor allem, wenn es viele abgeleitete Klassen gibt)
Gibt es eine tragbare und sauber (keine Flags herum) Weg dies zu implementieren ?. .. oder was ist falsch mit dem oben genannten d esign?
Edit: --------------------
Wie einige erwähnt haben, die rein virtuelle ist nicht das eigentliche Problem. Es tritt in den Destruktor der Basisklasse ein, während der Thread noch läuft. Die eigentliche Frage sollte vielleicht sein „? ist es eine Möglichkeit, eine Pre-destructor Methode in einer Basisklasse haben“
In Is there any automated way to implement post-constructor and pre-destructor virtual method calls? wies von Jeremy Friesner, gibt es eine interessante Idee:
- Herstellung Der Destruktor der Basis und abgeleitete Klassen, die so geschützt sind, können nicht aufgerufen werden.
- Den Destruktor von BaseClass virtuell machen.
- in der Basisklasse Implementierung Löschen(), die zuerst den Thread beendet und ruft dann den destructor (als virtuelle abgeleitete Destruktoren aufgerufen werden)
Warum ist Ihr Basisklassen-Destruktor nicht virtuell? –
Sie möchten keine virtuellen Funktionen von dtor aufrufen, nicht nur reine, normalerweise –
Pure virtual ist ein Red Hering hier. Das eigentliche Problem ist, dass 'Run' versucht, auf das Objekt zuzugreifen, wenn es nicht mehr existiert. Die Lösung besteht darin, das Eigentum richtig zu verwalten, z. Verwenden von 'std :: shared_ptr/weak_ptr' anstelle des rohen Zeigers. –