const getter-Methode mit CComCriticalSection schützen
-
Guten Morgen,
wie kann man eine einzeilige getterMethode gegen mehrfachen Zugriff aus verschiedenen Threads schützen?
short CObjectHandler::getNumberOfObjects() const //ist public { return m_nNumberOfCurrentObjects; }Folgendes Problem habe ich dabei entdeckt:
Zum Schutz vor mehrfachem Zugriff habe ich eine CComCriticalSection.Die CriticalSection ist eine Membervarable des ObjectHandlers. Da die getterMethode const ist(wie es sein soll) kann ich die Criticalsection nicht locken, bzw unlocken, da das Object verändert werden würde. Außerdem müsste ich die CritSec nach dem return entlocken, was ja nicht geht.
Bin mir jetzt nicht ganz sicher, muss diese einzeilige GetterMethode auch überhaupt gesichert werden muss?Eine mögliche Lösung wäre folgende, wobei da dann das const wegfallen muss:
short CObjectHandler::getNumberOfObjects() { short nNum = 0; m_critSec.Lock(); nNum = m_nNumberOfCurrentObjects; m_critSec.Unlock(); return nNum; }Was meint ihr?
-
Du könntest m_CritSect mutable machen, um die const-correctness zu wahren. RAII wäre in diesem Zusammenhang auch ganz hübsch:
class CriticalSectionLock { CriticalSection& CriticalSection_; public: CriticalSectionLock( CriticalSection& CS ) : CriticalSection_( CS ) { // Konstruktor betritt die CS CriticalSection_.Lock(); } ~CriticalSectionLock() { // Destruktor verlässt die CS CriticalSection_.Unlock(); } private: // Obj. nicht kopierbar, CriticalSectionLock( const CriticalSectionLock& op ); CriticalSectionLock& operator=( const CriticalSectionLock& op ); }; short CObjectHandler::getNumberOfObjects() const { CriticalSectionLock Lock( m_critSec ); return m_nNumberOfCurrentObjects; }Edit
Quelltext korrigiert
-
Danke! So werd ichs machen.
edit: hat der Unterstrich am Ende des Variabennames eine besondere Bedeutung?
-
Firewall schrieb:
edit: hat der Unterstrich am Ende des Variabennames eine besondere Bedeutung?
Ja. Soll deutlich machen, dass es sich um einen Membervariable handelt. so wie m_...
-
DocShoe schrieb:
Du könntest m_CritSect mutable machen, um die const-correctness zu wahren. RAII wäre in diesem Zusammenhang auch ganz hübsch:
class CriticalSectionLock { CriticalSection& CriticalSection_; public: CriticalSectionLock( CriticalSection& CS ) : CriticalSection_( CS ) { // Konstruktor betritt die CS CriticalSection_.Lock(); } ~CriticalSectionLock() { // Destruktor verlässt die CS CriticalSection_.Unlock(); } private: // Obj. nicht kopierbar, CriticalSectionLock( const CriticalSectionLock& op ); CriticalSectionLock& operator=( const CriticalSectionLock& op ); }; short CObjectHandler::getNumberOfObjects() const { CriticalSectionLock Lock( m_critSec ); return m_nNumberOfCurrentObjects; }Edit
Quelltext korrigiertFolgendes ist mir noch aufgefallen:
Da m_critSec kein Pointer ist, meckert der Compiler wenn ich in Zeile 26 die Critsec einfach so wie im Bsp übergebe.error C2248: "CCriticalSectionLock::CCriticalSectionLock": Kein Zugriff auf private Member, dessen Deklaration in der CCriticalSectionLock-Klasse erfolgte.Wenn ich CriticalSectionLock Lock( *m_critSec ); mach, dann geht es, aber ist es so auch richtig? Schützt dann die critsec auch wirklich?
-
Hi Firewall,
ich stelle mal ganz vorsichtig die Frage:
"Welchen Sinn macht es?"
Ich vermute du erhoffst dir etwas, was du leider nicht dadurch kriegen wirst...Gruß,
XSpille
-
@Firewall: nene, der meckert nicht. Nicht bei dem was hier an Code zu sehen ist.
Poste mal ein compilierbares Beispiel (also nicht compilierbar, aber wo der einzige Fehler der von dir genannte ist).Vermutlich wirst du beim basteln des Beispiels deinen Fehler schon finden, denn es muss fast was ganz triviales sein.
-
Ok, Fehler gefunden. War wirklich trivial. Tomaten auf den Augen und gleichzeitig ein Blackout... Man hat den Fehler vor den Augen und siehts nicht... War alles richtig mit meinem Programm bis auf den Aufruf:
CCriticalSectionLock( m_csAccessSecure);
-
Da m_critSec kein Pointer ist, meckert der Compiler wenn ich in Zeile 26 die Critsec einfach so wie im Bsp übergebe.
Oder ist da vielleicht ein K zu viel in "kein Pointer"?
Wenn m_critSec nämlich schon ein Zeiger ist, dann wäre das von dir beschriebene Verhalten mehr oder weniger normal.
(Wobei mich dann immer noch wundert dass er sagt "Kein Zugriff auf private Member" und nicht einfach "kein passender overload gefunden" oder sowas)
-
XSpilles Frage steht allerdings immer noch unbeantwortet im Raum. Was genau passiert denn eigentlich mit dem Rückgabewert, wird er z.B. benutzt, um Datenelemente anzufordern? Für sich allein betrachtet macht die Implementation der getNumberOfObjects() Methode zwar Sinn, aber vielleicht nicht in einem größeren Kontext.