#pragma once
class MyClass
{
public:
MyClass(void);
~MyClass(void);
private:
int myVariable;
void ThreadSafeWrite(int i);
int ThreadSafeRead();
public:
SetMyVariable(int i) {
ThreadSafeWrite(i);
}
int GetMyVariable(void) {
return ThreadSafeRead();
}
};
Now I'm not sure, do I have MyClass inherit CriticalSection? And how would I implement ThreadSafeRead and ThreadSafeWrite?
error C2530: 'myCS' : references must be initialized
#pragma once
#include "CriticalSection.h" // the header where you will copy/paste the CriticalSection class definition
class MyClass
{
public:
MyClass(void);
~MyClass(void);
private:
CriticalSection myCS;
int myVariable;
void ThreadSafeWrite(int i)
{
//myCS.Enter();
//myVariable = i;
//myCS.Leave();
Locker(&myCS);
myVariable = i;
}
int ThreadSafeRead()
{
Locker(&myCS);
return myVariable;
}
public:
void SetMyVariable(int i) {
ThreadSafeWrite(i);
}
int GetMyVariable(void) {
return ThreadSafeRead();
}
};
CriticalSection.h (I threw class Locker at the bottom):#pragma once
#ifdef _WIN32
# include <windows.h>
#else
# include <unistd.h>
# include <pthread.h>
#endif
/**
* @class A wrapper-class around Critical Section functionality, WIN32 & PTHREADS.
*/
class CriticalSection
{
public:
/**
* @brief CriticalSection class constructor.
*/
explicit CriticalSection(void)
{
#ifdef _WIN32
if (0 == InitializeCriticalSectionAndSpinCount(&m_cSection, 0))
throw("Could not create a CriticalSection");
#else
if (pthread_mutex_init(&m_cSection, NULL) != 0)
throw("Could not create a CriticalSection");
#endif
}; // CriticalSection()
/**
* @brief CriticalSection class destructor
*/
~CriticalSection(void)
{
Enter(); // acquire ownership (for pthread)
#ifdef _WIN32
DeleteCriticalSection(&m_cSection);
#else
pthread_mutex_destroy(&m_cSection);
#endif
}; // ~CriticalSection()
/**
* @fn void Enter(void)
* @brief Wait for unlock and enter the CriticalSection object.
* @see TryEnter()
* @return void
*/
void Enter(void)
{
#ifdef _WIN32
EnterCriticalSection(&m_cSection);
#else
pthread_mutex_lock(&m_cSection);
#endif
}; // Enter()
/**
* @fn void Leave(void)
* @brief Leaves the critical section object.
* This function will only work if the current thread
* holds the current lock on the CriticalSection object
* called by Enter()
* @see Enter()
* @return void
*/
void Leave(void)
{
#ifdef _WIN32
LeaveCriticalSection(&m_cSection);
#else
pthread_mutex_unlock(&m_cSection);
#endif
}; // Leave()
/**
* @fn bool TryEnter(void)
* @brief Attempt to enter the CriticalSection object
* @return bool(true) on success, bool(false) if otherwise
*/
bool TryEnter(void)
{
// Attempt to acquire ownership:
#ifdef _WIN32
return(TRUE == TryEnterCriticalSection(&m_cSection));
#else
return(0 == pthread_mutex_trylock(&m_cSection));
#endif
}; // TryEnter()
private:
#ifdef _WIN32
CRITICAL_SECTION m_cSection; //!< internal system critical section object (windows)
#else
pthread_mutex_t m_cSection; //!< internal system critical section object (*nix)
#endif
}; // class CriticalSection
class Locker
{
public:
Locker(CriticalSection *cs):myCS(cs){cs->Enter();}
~Locker(){myCS->Leave();}
private:
CriticalSection *myCS;
};
class Locker
{
public:
Locker(CriticalSection *cs){myCS = cs; myCS->Enter();}
~Locker(){myCS->Leave();}
private:
CriticalSection *myCS;
};
Locker(&myCS);
error C2530: 'myCS' : references must be initialized
{
public:
Locker(CriticalSection *cs){lockerCS = cs; lockerCS->Enter();}
~Locker(){lockerCS->Leave();}
private:
CriticalSection *lockerCS;
};
void ThreadSafeWrite(int i)
{
Locker locker = Locker(&myCS);
myVariable = i;
}
int ThreadSafeRead()
{
Locker locker = Locker(&myCS);
return myVariable;
}
void ThreadSafeWrite(int i)
{
Locker locker(&myCS);
myVariable = i;
}
int ThreadSafeRead()
{
Locker locker(&myCS);
return myVariable;
}
you do not need to make unnecessary class copies. Sorry for the mess. Thanks for the points though.
Locker locker = Locker(&myCS);
actually makes a copy? I've been wondering what the proper way is to instantiate a class and store it in a variable. I've been defining variable myClass in *.h:
private:
MyClass myClass;
and then in *.cpp setting myClass
myClass = MyClass(a,b,c);
I suppose there's a better way?
class A:
{
public:
A(int i, int j)
{
I = i; J =j;
}
private:
int I, J;
};
The constructor A(int i, int j) is not the only one that exists for your class. The C++ creates implicitly defined default constructor for you. Read here about this.A a = A(1,2);
What happens is:operator=(const A&)
, which is also implicitly defined by the compiler.