A class is also allowed to have static members, which can be either variables or functions. These are considered to be in the class’ scope, but aren’t treated as normal members; they have static storage duration (they exist from the start of the program to the end), aren’t tied to a particular instance of the class, and only one copy exists for the entire class.

class Example {
    static int num_instances;      // Static data member (static member variable).
    int i;                         // Non-static member variable.

    static std::string static_str; // Static data member (static member variable).
    static int static_func();      // Static member function.

    // Non-static member functions can modify static member variables.
    Example() { ++num_instances; }
    void set_str(const std::string& str);

int         Example::num_instances;
std::string Example::static_str = "Hello.";

// ...

Example one, two, three;
// Each Example has its own "i", such that:
//  (&one.i != &two.i)
//  (&one.i != &three.i)
//  (&two.i != &three.i).
// All three Examples share "num_instances", such that:
//  (&one.num_instances == &two.num_instances)
//  (&one.num_instances == &three.num_instances)
//  (&two.num_instances == &three.num_instances)

Static member variables are not considered to be defined inside the class, only declared, and thus have their definition outside the class definition; the programmer is allowed, but not required, to initialise static variables in their definition. When defining the member variables, the keyword static is omitted.

class Example {
    static int num_instances;               // Declaration.

    static std::string static_str;          // Declaration.

    // ...

int         Example::num_instances;         // Definition.  Zero-initialised.
std::string Example::static_str = "Hello."; // Definition.

Due to this, static variables can be incomplete types (apart from void), as long as they’re later defined as a complete type.

struct ForwardDeclared;

class ExIncomplete {
    static ForwardDeclared fd;
    static ExIncomplete    i_contain_myself;
    static int             an_array[];

struct ForwardDeclared {};

ForwardDeclared ExIncomplete::fd;
ExIncomplete    ExIncomplete::i_contain_myself;
int             ExIncomplete::an_array[5];

Static member functions can be defined inside or outside the class definition, as with normal member functions. As with static member variables, the keyword static is omitted when defining static member functions outside the class definition.

// For Example above, either...
class Example {
    // ...

    static int static_func() { return num_instances; }

    // ...

    void set_str(const std::string& str) { static_str = str; }

// Or...

class Example { /* ... */ };

int  Example::static_func() { return num_instances; }
void Example::set_str(const std::string& str) { static_str = str; }

If a static member variable is declared const but not volatile, and is of an integral or enumeration type, it can be initialised at declaration, inside the class definition.

enum E { VAL = 5 };

struct ExConst {
    const static int ci = 5;              // Good.
    static const E ce = VAL;              // Good.
    const static double cd = 5;           // Error.
    static const volatile int cvi = 5;    // Error.

    const static double good_cd;
    static const volatile int good_cvi;

const double ExConst::good_cd = 5;        // Good.
const volatile int ExConst::good_cvi = 5; // Good.

As of C++11, static member variables of LiteralType types (types that can be constructed at compile time, according to constexpr rules) can also be declared as constexpr; if so, they must be initialised within the class definition.

struct ExConstexpr {
    constexpr static int ci = 5;                      // Good.
    static constexpr double cd = 5;                   // Good.
    constexpr static int carr[] = { 1, 1, 2 };        // Good.
    static constexpr ConstexprConstructibleClass c{}; // Good.
    constexpr static int bad_ci;                      // Error.

constexpr int ExConstexpr::bad_ci = 5;                // Still an error.

If a const or constexpr static member variable is odr-used (informally, if it has its address taken or is assigned to a reference), then it must still have a separate definition, outside the class definition. This definition is not allowed to contain an initialiser.

struct ExODR {
    static const int odr_used = 5;

// const int ExODR::odr_used;

const int* odr_user = & ExODR::odr_used; // Error; uncomment above line to resolve.

As static members aren’t tied to a given instance, they can be accessed using the scope operator, ::.

std::string str = Example::static_str;

They can also be accessed as if they were normal, non-static members. This is of historical significance, but is used less commonly than the scope operator to prevent confusion over whether a member is static or non-static.

Example ex;
std::string rts = ex.static_str;

Class members are able to access static members without qualifying their scope, as with non-static class members.

class ExTwo {
    static int num_instances;
    int my_num;

    ExTwo() : my_num(num_instances++) {}

    static int get_total_instances() { return num_instances; }
    int get_instance_number() const { return my_num; }

int ExTwo::num_instances;