Page Content

Tutorials

Static Data Members And Static Member Functions In C++

Static Data Members And Static Member Functions

Static Data Members

Instead of being linked to specific instances of the class type, static data members are variables that are connected to the class as a whole.

  • Single Copy: No matter how many copies of a class are made, all objects share a static data member. All objects of the same class can see a static data member modification.
  • Lifetime: Static data members are assigned at the start of the program and stay until the end. Unlike local variables, they survive function termination.
  • Declaration and Definition: Static data members are declared in class declarations using the static keyword. It isn’t defined (memory allocated) in the class declaration however. Rather, static data members need to be specified and often initialised using the class name and the scope resolution operator (::) outside of the class body, normally in a source file. Throughout the external definition, the static keyword is not used again. Before the first object is created, they are initialised to zero if they aren’t expressly initialised.
  • Access: To access static data members directly, prefix the scope resolution operator with the class name (e.g., ClassName::staticMember). The class name indicates their independence, yet an object, reference, or pointer of the class type can access them.
  • Uses: access to shared resources and keeping class-wide information like object counters are common uses. Global variables are not necessary to communicate data among all objects of a class when static data members are used.

Static Member Functions

Instead of belonging to a particular object of the class, static member functions are those that are part of the class type itself.

  • No this Pointer: The fact that static member functions do not receive this pointer is the most important feature.
  • Access Limitations: Since static member functions lack this pointer, they can only access class-related static data or functions. Non-static class member methods require an object instance and this pointer to invoke. They do, however, have access to global data and functions.
  • Calling: Even in the event that there are no class objects, a static member function can be called. The class name and the scope resolution operator (ClassName::staticFunction(), for example) are the recommended methods for calling them. It is less frequent and semantically deceptive to call them through an object, even though it is syntactically feasible.
  • Restrictions: Static member functions are not able to be specified as virtual, volatile, or const. The same function cannot have both a static and a non-static version.
  • Uses: Utility functions that apply to the entire class, including those that pre-initialize private static data members or methods for creating objects (called constructors), are frequently utilised with them.

You can also read Order Of Execution Of Constructor & Destructor In C++

Code Example

#include <iostream>
#include <string> // Required for std::string
// Define a class to demonstrate static data members and static member functions
class Item {
private:
    int number;            // Non-static data member: unique to each object
    static int count;      // Static data member: shared by all objects 
public:
    // Constructor: Initializes 'number' and increments the shared 'count'
    Item(int a = 0) : number(a) { // Default parameter added for flexibility
        count++; // Increments the single shared count 
        std::cout << "Item object with number " << number << " created. Current total items: " << count << std::endl;
    }
    // Non-static member function: Operates on a specific object
    // and implicitly uses the 'this' pointer (though not explicitly shown here)
    void getdata() { // Renamed from set to getdata
        // This non-static method can access static members directly
        // because static members belong to the class, not a specific object
        std::cout << "Data for object " << number << " read. Count is now: " << count << std::endl;
    }
    // Static member function: Associated with the class, not an object.
    // It does NOT have a 'this' pointer [1, 42, 45, 48]
    static void showcount() { // Renamed from getcount to showcount
        // Can only directly access static data members or other static member functions 
        std::cout << "Current total number of Item objects (via static function): " << count << std::endl;
        // The following line would cause a compile-time error because 'number' is non-static
        // std::cout << "Object number (cannot access from static method): " << number << std::endl; 
    }
    // Destructor: Decrements the shared 'count' when an object is destroyed
    ~Item() {
        count--; // Decrements the shared count when an object goes out of scope
        std::cout << "Item object with number " << number << " destroyed. Remaining items: " << count << std::endl;
    }
};
// Definition and initialization of the static data member outside the class
// Memory is allocated for 'count' here 
// If not explicitly initialized, it would default to zero 
int Item::count = 0; // Explicitly initialized to 0.
int main() {
    std::cout << "--- Initial state (before any objects) ---" << std::endl;
    // Call static member function using the class name (no object needed) 
    Item::showcount(); 
    Item a(10); // Creates object 'a', constructor increments count
    Item b(20); // Creates object 'b', constructor increments count
    Item c(30); // Creates object 'c', constructor increments count
    std::cout << "\n--- After creating a, b, and c ---" << std::endl;
    // Call static member function again to see the updated shared count
    // All calls will show the same count because it's shared
    a.showcount(); // Possible to call via object, but not preferred 
    b.showcount();
    c.showcount();
    // Demonstrate modifying a non-static member (and implicitly accessing static count)
    a.getdata(); 
    b.getdata(); 
    c.getdata(); 
    std::cout << "\n--- End of main function ---" << std::endl;
    // Objects a, b, c go out of scope here, their destructors are called, decrementing 'count'
    return 0;
}

Output

--- Initial state (before any objects) ---
Current total number of Item objects (via static function): 0
Item object with number 10 created. Current total items: 1
Item object with number 20 created. Current total items: 2
Item object with number 30 created. Current total items: 3
--- After creating a, b, and c ---
Current total number of Item objects (via static function): 3
Current total number of Item objects (via static function): 3
Current total number of Item objects (via static function): 3
Data for object 10 read. Count is now: 3
Data for object 20 read. Count is now: 3
Data for object 30 read. Count is now: 3
--- End of main function ---
Item object with number 30 destroyed. Remaining items: 2
Item object with number 20 destroyed. Remaining items: 1
Item object with number 10 destroyed. Remaining items: 0

You can also read What Mean By ‘this’ Pointer In C++ With Code Example?

Agarapu Geetha
Agarapu Geetha
My name is Agarapu Geetha, a B.Com graduate with a strong passion for technology and innovation. I work as a content writer at Govindhtech, where I dedicate myself to exploring and publishing the latest updates in the world of tech.
Index