Static data members

In some cases, it's necessary and/or desirable for all objects of a class to share data. This is as close as we get to "global variables".

Consider an application that models a collection of car factories. You would certainly create a Factory class, a Car class and other related classes. One requirement of the application could be to count the number of cars produced at all of the factories. The variable that contains this data can't be in any Factory object (why not?), yet has to be available to all the Factory objects.

When a data member is defined inside a class, each object of that class type gets its own copy of that data member. Sometimes, as in this example, you want to have one variable that is shared by all objects of a particular class. This variable could be used by the objects to communicate with each other or to help coordinate the activities of the objects. It would have some advantages of a global variable, but be limited in its accessibility.

The mechanism for creating such a variable is to define it as a static data member. Think of static data members (and static functions) as belonging to the class rather than with objects of the class. In particular, defining a variable as a private static data member makes it usable only by objects of the class in which it is defined. Take a look at this example code from the text.

//---------------------------- // Modified Display 7.6 page 287-8 // from Savitch text to meet CMSC 202 // coding standards // // Example of static data member and static // member functions //------------------------------- //---------------- // Server.h //---------------- #include <iostream> using namespace std; class Server { public: Server(char letterName); void ServeOne( ) const; static int GetTurn( ); static bool StillOpen( ); private: static int m_turn; static int m_lastServed; static bool m_nowOpen; char m_name; }; //---------------------------------- // Server.cpp //---------------------------------- // memory allocation and initialization for // Server's (private) static data members // typically found in Server.cpp int Server::m_turn = 0; int Server::m_lastServed = 0; bool Server::m_nowOpen = true; // constructor Server::Server(char letterName) : m_name(letterName) { // no code } // static int Server::GetTurn( ) { m_turn++; return m_turn; } // static bool Server::StillOpen( ) { return m_nowOpen; } // services one customer void Server::ServeOne( ) const { if (m_nowOpen && m_lastServed < m_turn) { m_lastServed++; cout << "Server " << m_name << " now serving " << m_lastServed << endl; } if (m_lastServed >= m_turn) //Everyone served m_nowOpen = false; } //-------------------------------------------------- int main( ) { Server anne('A'), bob('B'); int number, count; do { cout << "How many in your group? "; cin >> number; cout << "Your turns are: "; for (count = 0; count < number; count++) cout << Server::GetTurn( ) << ' '; cout << endl; anne.ServeOne( ); bob.ServeOne( ); } while (Server::StillOpen( )); cout << "Now closing service.\n"; return 0; } Notice that the definition of the static data member DOES NOT allocate memory. The memory for the static data member must be allocated and initialized outside of the class.

Notice also that the functions GetTurn( ) and StillOpen( ) are declared as static. This means that they access static data members, but cannot access non-static data members of an object. Since static functions are thought of as part of the class, they are usually invoked using the class scope operator -- Server::StillOpen( ) rather than just StillOpen( );

Static data members may also be const. A const static data member is usually declared in the class and defined and initialized in a single source file (class.cpp) as described above. However, integral data types (int, long, char, etc) may be initialized when they are declared in the class.

//------------------ // Bob.h //------------------ class Bob { public: Bob( ); // other public stuff private: // okay to initialize integral types static const int m_age = 42; static const char m_middleInitial = 'K'; // no initialization allowed for others static const double m_salary; static const string m_name; }; //--------------------- // Bob.cpp //--------------------- #include "Bob.h" const double Bob::m_salary = 25000.00; const string Bob::m_name = "Robert K. Jones";

Last Modified: Monday, 28-Aug-2006 10:15:53 EDT