Demonstrating static Data Members

The program of Figs. 9.279.29 demonstrates a private static data member called count (Fig. 9.27, line 24) and a public static member function called getCount (Fig. 9.27, line 18). In Fig. 9.28, line 8 defines and initializes the data member count to zero at global namespace scope and lines 12–15 define static member function getCount. Notice that neither line 8 nor line 12 includes keyword static, yet both lines define static class members. The static keyword cannot be applied to a member definition that appears outside the class definition. Data member count maintains a count of the number of objects of class Employee that have been instantiated. When objects of class Employee exist, member count can be referenced through any member function of an Employee object—in Fig. 9.28, count is referenced by both line 22 in the constructor and line 32 in the destructor.


 1   // Fig. 9.27: Employee.h
 2   // Employee class definition with a static data member to
 3   // track the number of Employee objects in memory
 4   #ifndef EMPLOYEE_H
 5   #define EMPLOYEE_H
 6
 7   #include <string>
 8
 9   class Employee
10   {
11   public:
12      Employee( const std::string &, const std::string & ); // constructor
13      ~Employee(); // destructor
14      std::string getFirstName() const; // return first name
15      std::string getLastName() const; // return last name
16
17      // static member function                                          
18      static unsigned int getCount(); // return # of objects instantiated
19   private:
20      std::string firstName;
21      std::string lastName;
22
23      // static data
24      static unsigned int count; // number of objects instantiated
25   }; // end class Employee
26
27   #endif


Fig. 9.27. Employee class definition with a static data member to track the number of Employee objects in memory.


 1   // Fig. 9.28: Employee.cpp
 2   // Employee class member-function definitions.
 3   #include <iostream>
 4   #include "Employee.h" // Employee class definition
 5   using namespace std;
 6
 7   // define and initialize static data member at global namespace scope
 8   unsigned int Employee::count = 0; // cannot include keyword static   
 9
10   // define static member function that returns number of         
11   // Employee objects instantiated (declared static in Employee.h)
12   unsigned int Employee::getCount()                               
13   {                                                               
14      return count;                                                
15   } // end static function getCount                               
16
17   // constructor initializes non-static data members and
18   // increments static data member count
19   Employee::Employee( const string &first, const string &last )
20      : firstName( first ), lastName( last )
21   {
22      ++count; // increment static count of employees
23      cout << "Employee constructor for " << firstName
24         << ' ' << lastName << " called." << endl;
25   } // end Employee constructor
26
27   // destructor deallocates dynamically allocated memory
28   Employee::~Employee()
29   {
30      cout << "~Employee() called for " << firstName
31         << ' ' << lastName << endl;
32      --count; // decrement static count of employees
33   } // end ~Employee destructor
34
35   // return first name of employee
36   string Employee::getFirstName() const
37   {
38      return firstName; // return copy of first name
39   } // end function getFirstName
40
41   // return last name of employee
42   string Employee::getLastName() const
43   {
44      return lastName; // return copy of last name
45   } // end function getLastName


Fig. 9.28. Employee class member-function definitions.


 1   // Fig. 9.29: fig09_29.cpp
 2   // static data member tracking the number of objects of a class.
 3   #include <iostream>
 4   #include "Employee.h" // Employee class definition
 5   using namespace std;
 6
 7   int main()
 8   {
 9      // no objects exist; use class name and binary scope resolution
10      // operator to access static member function getCount
11      cout << "Number of employees before instantiation of any objects is "
12         << Employee::getCount() << endl; // use class name
13
14      // the following scope creates and destroys
15      // Employee objects before main terminates
16      {
17         Employee e1( "Susan", "Baker" );
18         Employee e2( "Robert", "Jones" );
19
20         // two objects exist; call static member function getCount again
21         // using the class name and the scope resolution operator
22         cout << "Number of employees after objects are instantiated is "
23            << Employee::getCount();
24
25         cout << " Employee 1: "
26            << e1.getFirstName() << " " << e1.getLastName()
27            << " Employee 2: "
28            << e2.getFirstName() << " " << e2.getLastName() << " ";
29      } // end nested scope in main
30
31      // no objects exist, so call static member function getCount again
32      // using the class name and the scope resolution operator
33      cout << " Number of employees after objects are deleted is "
34         << Employee::getCount() << endl;
35   } // end main


Number of employees before instantiation of any objects is 0
Employee constructor for Susan Baker called.
Employee constructor for Robert Jones called.
Number of employees after objects are instantiated is 2

Employee 1: Susan Baker
Employee 2: Robert Jones

~Employee() called for Robert Jones
~Employee() called for Susan Baker

Number of employees after objects are deleted is 0


Fig. 9.29. static data member tracking the number of objects of a class.

Figure 9.29 uses static member function getCount to determine the number of Employee objects in memory at various points in the program. The program calls Employee::getCount() before any Employee objects have been created (line 12), after two Employee objects have been created (line 23) and after those Employee objects have been destroyed (line 34). Lines 16–29 in main define a nested scope. Recall that local variables exist until the scope in which they’re defined terminates. In this example, we create two Employee objects in lines 17–18 inside the nested scope. As each constructor executes, it increments class Employee’s static data member count. These Employee objects are destroyed when the program reaches line 29. At that point, each object’s destructor executes and decrements class Employee’s static data member count.

A member function should be declared static if it does not access non-static data members or non-static member functions of the class. Unlike non-static member functions, a static member function does not have a this pointer, because static data members and static member functions exist independently of any objects of a class. The this pointer must refer to a specific object of the class, and when a static member function is called, there might not be any objects of its class in memory.


Image Common Programming Error 9.6

Using the this pointer in a static member function is a compilation error.



Image Common Programming Error 9.7

Declaring a static member function const is a compilation error. The const qualifier indicates that a function cannot modify the contents of the object on which it operates, but static member functions exist and operate independently of any objects of the class.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.40.129