003
28.11.2002, 13:54 Uhr
virtual
Sexiest Bit alive (Operator)
|
Hi,
wer C++ mag, macht da eine kleine Klasse zu. Meine erste Überlegung dazu ist ein kleines Template (was haltet ihr davon?):
C++: |
// RecursionWatcher.h template<void* T> class RecursionWatcher { static int m_nDepth;
public: RecursionWatcher() { ++m_nDepth; }; ~RecursionWatcher() { --m_nDepth; };
bool checkDepth(int p_nMaxDepth) const { return p_nMaxDepth<m_nDepth; }; int getDepth() const { return m_nDepth; }; };
template<void* T> int RecursionWatcher<T>::m_nDepth = 0;
|
Einsetzen kann man das zB so:
C++: |
#include <iostream> #include <cstdlib> #include <ctime> #include "RecursionWatcher.h"
using namespace std;
int sum(int i) { RecursionWatcher<(void*)sum> watcher; if (watcher.checkDepth(10) || i<0) return 0; return i + sum(i-1); }
int main() { srand(time(NULL)); int n = rand()%2000; cout << "Summe von " << n-9 << " bis " << n << ": " << sum(n) << endl; }
|
Im Prinzip ist die Klasse nix anderes als ein static int, welches durch die Konstruktion von watcher in sum automatisch hochgezählt wird und durch die destruktion beim verlassen der Funktion runtergezählt wird. Mit checkDepth kann man gegen die grenze der max. gewünschten Rekursionstiefe checken...
Template muss das ganze sein, weil so ein Watcher ja in mehreren Funktionen verwendet werden soll. Daher übergibt man als Templateparameter einfach die Addresse der Funktion, wodurch das Template immer passend zur Funktion instanziiert wird.
Den Vorteil, den diese Methode bietet, sehe ich darin, dass bei komplexeren Funktionen sich ansonsten schnell mal der Fehler einschleicht, daß man vergisst, der RecursionCounter zu dekrementieren. Und auch bei einfachen Funktionen sollte das Template eigentlich keinen (nennenswerten) Overhead nach sich ziehen. -- Gruß, virtual Quote of the Month Ich eß' nur was ein Gesicht hat (Creme 21) Dieser Post wurde am 28.11.2002 um 13:57 Uhr von virtual editiert. |