Static Variables In C++ Classes

It turns out that static variables in C++ classes are actually pretty cool.

If you declare a static variable at class level (i.e. inside the class declaration), then you are creating a variable that will

a) be accessible to all objects created from that class, and
b) be available even before you have created a single instance of that class.

Essentially, every object you create sees the same static variable, so anything that one object does to that variable (such as increment the value), all the other objects can also see.

Super useful, eh?

Point b above also means that you absolutely have to initialise your static variable in the class file. In fact, it’s a compile error if you don’t, so don’t worry about forgetting to do this.

Whether or not external code (i.e. program code outside the class) can see this variable depends on whether you create it to be private or public.

What about a static variable declared in a class method?

Good question.

If you create a static variable inside a class method, then you are still creating a variable that will be shared by all objects, but it will not be created until the class function is called, and you will only be able to access it from inside the function.

Code example

As usual, seeing these variables in code helps clarify the points above.

Here we have three files: main.cpp, DiskDrive.cpp and DiskDrive.h.

Compile with:

g++ main.cpp DiskDrive.cpp

File 1: main.cpp

#include <iostream>
#include <unistd.h>
#include "DiskDrive.h"

int main()
{
    DiskDrive d1;
    sleep(1);
    DiskDrive d2;
    sleep (1);
    DiskDrive d3;

    std::cout << "Total number of drives is ";
    std::cout << d2.GetDriveCount() << std::endl;

    // You can also access the static class variable directly
    // because it is declared as public:
    std::cout << DiskDrive::TotalDiskDrives << std::endl;
}

File 2: DiskDrive.h

class DiskDrive
{
public:
    DiskDrive();
    ~DiskDrive();
    int GetDriveCount();
    void Init();
    static int TotalDiskDrives;
};

File 3: DiskDrive.cpp

#include <iostream>
#include <time.h>
#include "DiskDrive.h"

//static
int DiskDrive::TotalDiskDrives = 0;

//constructor
DiskDrive::DiskDrive()
{
    ++TotalDiskDrives;
    Init();
}

//destructor
DiskDrive::~DiskDrive()
{
    if (TotalDiskDrives > 0)
    {
        --TotalDiskDrives;
    }
}

int DiskDrive::GetDriveCount()
{
    return TotalDiskDrives;
}

void DiskDrive::Init()
{
    static time_t lastDriveAdded = 0;

    char previous[256] = {0};
    strftime(previous, 20, "%Y-%m-%d %H:%M:%S", localtime(&lastDriveAdded));
    std::cout << "Previous drive added: " << previous << std::endl;
  
    time(&lastDriveAdded);

    char buffer[256] = {0};
    strftime(buffer, 20, "%Y-%m-%d %H:%M:%S", localtime(&lastDriveAdded));
    std::cout << "Last drive added: " << buffer << std::endl;
}

The output of this program is:

class_static

We can see here that although we are interacting with three different objects (three different drives) in the main.cpp file, the output from the static variables is acting as though it came from a single instance.

Both the class static (drive count) and the class method static (last time drive added) are recording details for all drive objects.

 


3 Comments

  1. duskoKoscica
    Posted 16 December 2014 at 13:58 | Permalink

    What is MVVAH!

    Or is it a double W?

    And for static it is OK to us it in situations that you have some resource like> picture, sound, icon, name of the file etc…

    As well!

  2. Posted 20 December 2014 at 09:33 | Permalink

    Yes, a static would be fine to refer to an external file path. You could use the extern keyword to ensure you give each file access to the static path – I’ll be writing about that in the New Year.

  3. Posted 29 December 2014 at 04:55 | Permalink

    Static variable in c++ was one of my weak point. I am also an instructor and teach C++ in Urdu (Urdu is my native language) but your article helped me a lot. Thank you.