definiamo una classe base Synchronizable:
class Synchronizable
{
friend class Synchonizer;
CCriticalSection theLock;
/* O qualunque implementazione di un oggetto del genere fornito dalla libreria */
protected:
void Lock() { theLock.Lock(); }
void Unlock() { theLock.Unlock(); }
};
e poi una classe Synchonizer:
class Synchronizer
{
Synchronizable *s;
public:
Synchronizer(Synchronizable *_s): s(_s)
{ s->Lock(); }
~Synchronizer() { s->Unlock(); }
};
A questo punto, sarà possibile implementare delle classi derivate da Synchronizable, e laddove si vogliano sincronizzare le funzioni membro basterà:
void MyClass::doSomething()
{
Synchronizer s(this);
.....
}
All'uscita dal metodo (sia attraverso una return che a fronte dell'innalzamento di un'eccezione), il distruttore di s effettuerà l'Unlock.
Inoltre è possibile usare questa tecnica anche all'interno di scope diversi dal corpo dell'intero metodo:
void MyClass::doSomething()
{
...
{
Synchronizer s(this);
// questo scope è in critical section
....
}
... // qui siamo fuori dalla cs
}
Ovviamente questa tecnica non impedisce l'utilizzo "manuale" dei metodi protetti Lock() e Unlock()...