What is static member function in C?

Improve Article

Save Article

Like Article

Static data members are class members that are declared using static keywords. A static member has certain special characteristics. These are:

  • Only one copy of that member is created for the entire class and is shared by all the objects of that class, no matter how many objects are created.
  • It is initialized before any object of this class is being created, even before main starts.
  • It is visible only within the class, but its lifetime is the entire program

Syntax

static data_type data_member_name;

#include <iostream>

using namespace std;

class A

{

public:

    A() { cout << "A's Constructor Called " << endl;  }

};

class B

{

    static A a;

public:

    B() { cout << "B's Constructor Called " << endl; }

};

int main()

{

    B b;

    return 0;

}

Output: 

B's Constructor Called

The above program calls only B’s constructor, it doesn’t call A’s constructor. The reason for this is simple, static members are only declared in a class declaration, not defined. They must be explicitly defined outside the class using the scope resolution operator. 
If we try to access static member ‘a’ without an explicit definition of it, we will get a compilation error. For example, the following program fails in the compilation.

#include <iostream>

using namespace std;

class A

{

    int x;

public:

    A() { cout << "A's constructor called " << endl;  }

};

class B

{

    static A a;

public:

    B() { cout << "B's constructor called " << endl; }

    static A getA() { return a; }

};

int main()

{

    B b;

    A a = b.getA();

    return 0;

}

Output: 

Compiler Error: undefined reference to `B::a'

If we add the definition of a the program will work fine and will call A’s constructor. See the following program.

#include <iostream>

using namespace std;

class A

{

    int x;

public:

    A() { cout << "A's constructor called " << endl;  }

};

class B

{

    static A a;

public:

    B() { cout << "B's constructor called " << endl; }

    static A getA() { return a; }

};

A B::a; 

int main()

{

    B b1, b2, b3;

    A a = b1.getA();

    return 0;

}

Output: 

A's constructor called B's constructor called B's constructor called B's constructor called

Note that the above program calls B’s constructor 3 times for 3 objects (b1, b2, and b3), but calls A’s constructor only once. The reason is, static members are shared among all objects. That is why they are also known as class members or class fields. Also, static members can be accessed without any object, see the below program where static member ‘a’ is accessed without any object.

#include <iostream>

using namespace std;

class A

{

    int x;

public:

    A() { cout << "A's constructor called " << endl;  }

};

class B

{

    static A a;

public:

    B() { cout << "B's constructor called " << endl; }

    static A getA() { return a; }

};

A B::a; 

int main()

{

    A a = B::getA();

    return 0;

}

Output: 

A's constructor called

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
 


From cppreference.com

Inside a class definition, the keyword static declares members that are not bound to class instances.

Outside a class definition, it has a different meaning: see storage duration.

[edit] Syntax

A declaration for a static member is a member declaration whose declaration specifiers contain the keyword static. The keyword static usually appears before other specifiers (which is why the syntax is often informally described as static data-member or static member-function), but may appear anywhere in the specifier sequence.

The name of any static data member and static member function must be different from the name of the containing class.

[edit] Explanation

Static members of a class are not associated with the objects of the class: they are independent variables with static or thread (since C++11) storage duration or regular functions.

The static keyword is only used with the declaration of a static member, inside the class definition, but not with the definition of that static member:

class X { static int n; }; // declaration (uses 'static') int X::n = 1; // definition (does not use 'static')

The declaration inside the class body is not a definition and may declare the member to be of incomplete type (other than void), including the type in which the member is declared:

struct Foo;   struct S { static int a[]; // declaration, incomplete type static Foo x; // declaration, incomplete type static S s; // declaration, incomplete type (inside its own definition) };   int S::a[10]; // definition, complete type struct Foo {}; Foo S::x; // definition, complete type S S::s; // definition, complete type

However, if the declaration uses constexpr or inline (since C++17) specifier, the member must be declared to have complete type.

(since C++11)

To refer to a static member m of class T, two forms may be used: qualified name T::m or member access expression E.m or E->m, where E is an expression that evaluates to T or T* respectively. When in the same class scope, the qualification is unnecessary:

struct X { static void f(); // declaration static int n; // declaration };   X g() { return X(); } // some function returning X   void f() { X::f(); // X::f is a qualified name of static member function g().f(); // g().f is member access expression referring to a static member function }   int X::n = 7; // definition   void X::f() // definition { n = 1; // X::n is accessible as just n in this scope }

Static members obey the class member access rules (private, protected, public).

[edit] Static member functions

Static member functions are not associated with any object. When called, they have no this pointer.

Static member functions cannot be virtual, const, volatile, or ref-qualified.

The address of a static member function may be stored in a regular pointer to function, but not in a pointer to member function.

[edit] Static data members

Static data members are not associated with any object. They exist even if no objects of the class have been defined. There is only one instance of the static data member in the entire program with static storage duration, unless the keyword thread_local is used, in which case there is one such object per thread with thread storage duration (since C++11).

Static data members cannot be mutable.

Static data members of a class in namespace scope have external linkage if the class itself has external linkage (is not a member of unnamed namespace). Local classes (classes defined inside functions) and unnamed classes, including member classes of unnamed classes, cannot have static data members.

A static data member may be declared inline. An inline static data member can be defined in the class definition and may specify an initializer. It does not need an out-of-class definition:

struct X { inline static int n = 1; };

(since C++17)

[edit] Constant static members

If a static data member of integral or enumeration type is declared const (and not volatile), it can be initialized with an initializer in which every expression is a constant expression, right inside the class definition:

struct X { const static int n = 1; const static int m{2}; // since C++11 const static int k; }; const int X::k = 3;

If a static data member of LiteralType is declared constexpr, it must be initialized with an initializer in which every expression is a constant expression, right inside the class definition:

struct X { constexpr static int arr[] = { 1, 2, 3 }; // OK constexpr static std::complex<double> n = {1,2}; // OK constexpr static int k; // Error: constexpr static requires an initializer };

(since C++11)

If a const non-inline (since C++17) static data member or a constexpr static data member (since C++11)(until C++17) is odr-used, a definition at namespace scope is still required, but it cannot have an initializer. A definition may be provided even though redundant (since C++17).

struct X { static const int n = 1; static constexpr int m = 4; };   const int *p = &X::n, *q = &X::m; // X::n and X::m are odr-used const int X::n; // … so a definition is necessary constexpr int X::m; // … (except for X::m in C++17)

If a static data member is declared constexpr, it is implicitly inline and does not need to be redeclared at namespace scope. This redeclaration without an initializer (formerly required as shown above) is still permitted, but is deprecated.

(since C++17)

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 194 C++98 (static) member function names can be the same as the class name naming restriction added (including
non-static member functions)

[edit] References

  • C++23 standard (ISO/IEC 14882:2023):
  • 11.4.9 Static members [class.static]

  • C++20 standard (ISO/IEC 14882:2020):
  • 11.4.8 Static members [class.static]

  • C++17 standard (ISO/IEC 14882:2017):
  • 12.2.3 Static members [class.static]

  • C++14 standard (ISO/IEC 14882:2014):
  • 9.4 Static members [class.static]

  • C++11 standard (ISO/IEC 14882:2011):
  • 9.4 Static members [class.static]

  • C++98 standard (ISO/IEC 14882:1998):
  • 9.4 Static members [class.static]

[edit] See also

Última postagem

Tag