Given all that I hear about the problems with global variables, is it possible to declare a windows CRITICAL_SECTION object as a member of a base class that will not be created for each derived class? I want to implement an instance counter that is threadsafe, so I thought about this and the best I can come up with, at the moment, is the following:

class mammal
{
protected:
     int myCount;  
     CRITICAL_SECTION myCS;
public:
     mammal();
     ~mammal();
     virtual void Increment()=0;
     virtual void Decrement()=0;
     virtual void GetCount(int& myVal)=0;
     virtual void walk()=0;
//.  more mammal functions here
//.
//.

};

mammal::mammal()
{
     myCount = 0;
     InitializeCriticalSection(myCS);
}

mammal::~mammal()
{
     DeleteCriticalSection(myCS);
}


class dog: virtual public mammal
{
public:
     dog();
    ~dog();
     void Increment();
     void Decrement();
     void Getcount(int& myVal);
     void walk();
// more mammal functions
//
//
};

dog::dog()
{
     Increment();
}
dog::~dog()
{
     Decrement();
}
void dog::Increment()
{
     EnterCriticalSection(myCS);
     myCount++;
     LeaveCriticalSection(myCS);

}

void dog::Decrement()
{
     EnterCriticalSection(myCS);
     myCount--;
     LeaveCriticalSection(myCS);

}

int dog::GetCount(int& myVal)
{
     EnterCriticalSection(myCS);
     myVal = myCount;
     LeaveCriticalSection(myCS);
}

Does this look like a reasonable way to implement CRITICAL_SECTION without making it a global?

> is it possible to declare a windows CRITICAL_SECTION object as a member of a base class
> that will not be created for each derived class?
yes

> Does this look like a reasonable way to implement CRITICAL_SECTION
yes, this is the normal way when you want to synchronize access to instances. though, in c++ code, use of RAII is canonical. http://jrdodds.blogs.com/blog/2004/08/raii_in_c.html

> I want to implement an instance counter that is threadsafe
if the only thing that you want to synchronize is a variable having an integral value, a critical section is an overkill. using InterlockedIncrement /InterlockedDecrement would be simpler and more efficient. http://msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx

Please note that you must create a copy constructor! Because else if you do Object = Object2 then they will share a critical section and will both try to dealocate it.

Comments
right!

Please note that you must create a copy constructor! Because else if you do Object = Object2 then they will share a critical section and will both try to dealocate it.

I'm not sure if this is correct. If Object's class is derived from mammal, then it would share the same copy of mammal that all other derived classes share, as it would also inherit using the virtual keyword. The last derived class will call the base class constructor, and the others will ignore it. I am assuming that when objects are destroyed, they will follow the same convention, and the base class destructor won't be called until the last derived object is destroyed...but am not sure.

This article has been dead for over six months. Start a new discussion instead.