static关键字及其在C ++中的各种用法

关键字static是C ++中的一些含义,我发现它非常容易混淆,而且我永远无法绕开它的实际工作方式。

从我所了解的情况来看,存在static存储持续时间,这意味着它在全局情况下会持续到程序的生命周期,但是当您谈到本地时,这意味着它默认为零初始化。

C ++标准对于关键字为static类数据成员说:

3.7.1静态存储时间[basic.stc.static]

3关键字static可以用来声明一个静态存储持续时间的局部variables。

4类定义中应用于类数据成员的关键字static为数据成员提供静态存储持续时间。

这与局部variables是什么意思? 这是一个函数局部variables? 因为当你声明一个局部static的函数时,它只会被初始化一次,所以它第一次进入这个函数。

它也只是谈论关于类成员的存储时间,那么它是非实例特定的,这也是一个static否定的属性? 或者是那个存储时间?

那么static和文件范围的情况呢? 是否所有的全局variables被认为默认具有静态存储持续时间? 以下(来自第3.7.1节)似乎表明:

1所有没有dynamic存储持续时间的variables,没有线程存储持续时间,并且不在本地有静态存储持续时间。 这些实体的存储应在程序期间持续(3.6.2,3.6.3)

static如何与variables的链接相关联?

这整个static关键字是彻头彻尾的混乱,有人可以澄清它的英语的不同用途,也告诉我什么时候初始化static类成员?

variables:

staticvariables存在于其定义翻译单元的“生命周期” ,并且:

  • 如果它在命名空间范围内(即在函数和类之外),则不能从任何其他翻译单元访问它。 这被称为“内部联动”。 (不要在标题中这样做,这只是一个可怕的想法,你最终在每个翻译单元中有一个单独的variables,这是疯狂的混淆)
  • 如果它是一个函数中的variables,那么它不能从函数外部访问,就像任何其他局部variables一样。 (这是他们提到的地方)
  • 类成员由于static而没有受限制的范围,但可以从类以及实例(如std::string::npos )中std::string::npos 。 [注意:你可以在一个类中声明静态成员,但是它们通常仍然应该在一个翻译单元(cpp文件)中定义 ,因此每个类只有一个]

在执行翻译单元中的任何function之前(可能在main开始执行之后),在该翻译单元中具有静态存储持续时间的variables将被“恒定初始化”(在可能的情况下为constexpr ,否则为零),然后非本地人“dynamic初始化” 按照它们在翻译单元中定义的顺序 (对于像std::string="HI";不是constexpr )。 最后,函数本地静态在第一次执行“到达”它们被声明的行时被初始化。 它们都以与初始化相反的顺序销毁。

最简单的方法是将所有不是constexpr静态variables初始化为函数静态constexprvariables,这样可以确保所有静态variables/全局variables在您尝试使用它们时都能够正确初始化,从而防止静态初始化命令失败 。

 T& get_global() { static T global = initial_value(); return global; } 

要小心,因为当规范说默认情况下命名空间范围variables具有“静态存储持续时间”时,它们意味着“翻译单位的生命周期”位,但这并不意味着它不能在文件之外访问。

function

static通常被用作类成员函数,而且很less用于独立函数。

静态成员函数与常规成员函数的不同之处在于它可以在没有实例的情况下被调用,并且由于它没有实例,所以它不能访问类的非静态成员。 当你想要一个绝对不会引用任何实例成员的类或者用于pipe理static成员variables的类的时候,静态variables是很有用的。

 struct A { A() {++A_count;} A(const A&) {++A_count;} A(A&&) {++A_count;} ~A() {--A_count;} static int get_count() {return A_count;} private: static int A_count; } int main() { A var; int c0 = var.get_count(); //some compilers give a warning, but it's ok. int c1 = A::get_count(); //normal way } 

static自由函数意味着该函数不会被其他任何翻译单元引用,因此链接器可以完全忽略它。 这有几个目的:

  • 可以在cpp文件中使用,以保证函数不会从其他文件中使用。
  • 可以放在标题中,每个文件都有它自己的函数副本。 没用,因为内联几乎是一样的东西。
  • 通过减less工作加快链接时间
  • 可以在每个TU中放一个同名的函数,它们都可以做不同的事情。 例如,你可以在每个cpp文件中放一个static void log(const char*) {} ,并且它们都可以以不同的方式login。

静态存储时间意味着variables在程序的整个生存期内驻留在内存中的相同位置。

联系与此正交。

我认为这是你能做的最重要的区别。 理解这一点,其余的,以及记住它,应该是容易的(不直接@ @托尼,而是谁将来可能会读这个)。

关键字static可以用来表示内部链接静态存储,但实质上不同。

这与局部variables是什么意思? 这是一个函数局部variables?

是。 无论何时初始化variables(首次调用函数,执行path到达声明点时),程序的生命周期都将驻留在内存中的相同位置。 在这种情况下, static给它静态存储。

那么静态和文件范围的情况呢? 是否所有的全局variables被认为默认具有静态存储持续时间?

是的,所有的全局variables都有静态的存储时间(现在我们已经清楚了这个意思)。 命名空间范围的variables不是用static声明的,因为这会给它们内部的连接,所以每个翻译单元都有一个variables。

静态如何与variables的链接相关联?

它提供了名称空间范围的variables内部链接。 它给成员和局部variables的静态存储时间。

让我们来展开所有这些:

 // static int x; //internal linkage //non-static storage - each translation unit will have its own copy of x //NOT A TRUE GLOBAL! int y; //static storage duration (can be used with extern) //actual global //external linkage struct X { static int x; //static storage duration - shared between classes }; void foo() { static int x; //static storage duration - shared between calls } 

这整个静态关键字是彻头彻尾的混乱

当然,除非你熟悉它。 :)为了避免在语言中添加新的关键字,委员会重新使用了这一个,国际海事组织,这个效果 – 混乱。 它被用来表示不同的东西(我可能会说,可能是反对的东西)。

其实很简单。 如果您在函数的作用域中将variables声明为静态,则在对该函数的连续调用之间将保留其值。 所以:

 int myFun() { static int i=5; i++; return i; } int main() { printf("%d", myFun()); printf("%d", myFun()); printf("%d", myFun()); } 

将显示678而不是666 ,因为它会记住递增的值。

至于静态成员,他们保持对class级实例的价值。 所以下面的代码:

 struct A { static int a; }; int main() { A first; A second; first.a = 3; second.a = 4; printf("%d", first.a); } 

将打印4,因为first.a和second.a本质上是相同的variables。 至于初始化,看到这个问题。

当你在文件范围声明一个staticvariables的时候,那个variables只能在那个特定的文件中使用(技术上说,*翻译单元,但是不要太复杂)。 例如:

a.cpp

 static int x = 7; void printax() { cout << "from a.cpp: x=" << x << endl; } 

b.cpp

 static int x = 9; void printbx() { cout << "from b.cpp: x=" << x << endl; } 

main.cpp中:

 int main(int, char **) { printax(); // Will print 7 printbx(); // Will print 9 return 0; } 

对于局部variables, static意味着该variables将被初始化为零, 在调用之间保持其值:

 unsigned int powersoftwo() { static unsigned lastpow; if(lastpow == 0) lastpow = 1; else lastpow *= 2; return lastpow; } int main(int, char **) { for(int i = 0; i != 10; i++) cout << "2^" << i << " = " << powersoftwo() << endl; } 

对于variables,这意味着该类的所有成员之间只共享该variables的单个实例。 根据权限,variables可以使用完全限定的名称从类外部访问。

 class Test { private: static char *xxx; public: static int yyy; public: Test() { cout << this << "The static class variable xxx is at address " << static_cast<void *>(xxx) << endl; cout << this << "The static class variable yyy is at address " << static_cast<void *>(&y) << endl; } }; // Necessary for static class variables. char *Test::xxx = "I'm Triple X!"; int Test::yyy = 0; int main(int, char **) { Test t1; Test t2; Test::yyy = 666; Test t3; }; 

将非类函数标记为static函数只能从该文件访问,而不能从其他文件访问。

a.cpp

 static void printfilename() { // this is the printfilename from a.cpp - // it can't be accessed from any other file cout << "this is a.cpp" << endl; } 

b.cpp

 static void printfilename() { // this is the printfilename from b.cpp - // it can't be accessed from any other file cout << "this is b.cpp" << endl; } 

对于类成员函数,将它们标记为static意味着函数不需要在对象的特定实例上调用(即,它没有this指针)。

 class Test { private: static int count; public: static int GetTestCount() { return count; }; Test() { cout << this << "Created an instance of Test" << endl; count++; } ~Test() { cout << this << "Destroyed an instance of Test" << endl; count--; } }; int Test::count = 0; int main(int, char **) { Test *arr[10] = { NULL }; for(int i = 0; i != 10; i++) arr[i] = new Test(); cout << "There are " << Test::GetTestCount() << " instances of the Test class!" << endl; // now, delete them all except the first and last! for(int i = 1; i != 9; i++) delete arr[i]; cout << "There are " << Test::GetTestCount() << " instances of the Test class!" << endl; delete arr[0]; cout << "There are " << Test::GetTestCount() << " instances of the Test class!" << endl; delete arr[9]; cout << "There are " << Test::GetTestCount() << " instances of the Test class!" << endl; return 0; } 

静态variables在类的每个实例之间共享,而不是每个类都有自己的variables。

 class MyClass { public: int myVar; static int myStaticVar; }; //Static member variables must be initialized. Unless you're using C++11, or it's an integer type, //they have to be defined and initialized outside of the class like this: MyClass::myStaticVar = 0; MyClass classA; MyClass classB; 

“MyClass”的每个实例都有自己的“myVar”,但共享相同的“myStaticVar”。 事实上,你甚至不需要MyClass的实例来访问“myStaticVar”,你可以像这样在类之外访问它:

 MyClass::myStaticVar //Assuming it's publicly accessible. 

在函数内部作为局部variables使用(而不是作为类成员variables)时,static关键字会有所不同。 它允许你创build一个持久variables,而不用提供全局范围。

 int myFunc() { int myVar = 0; //Each time the code reaches here, a new variable called 'myVar' is initialized. myVar++; //Given the above code, this will *always* print '1'. std::cout << myVar << std::endl; //The first time the code reaches here, 'myStaticVar' is initialized. But ONLY the first time. static int myStaticVar = 0; //Each time the code reaches here, myStaticVar is incremented. myStaticVar++; //This will print a continuously incrementing number, //each time the function is called. '1', '2', '3', etc... std::cout << myStaticVar << std::endl; } 

在持久性方面,这是一个全局variables…但是没有在范围/可访问性方面是全球性的。

你也可以有静态成员函数。 静态函数基本上是非成员函数,但在类名称的命名空间内,并且可以私有对类成员的访问。

 class MyClass { public: int Func() { //...do something... } static int StaticFunc() { //...do something... } }; int main() { MyClass myClassA; myClassA.Func(); //Calls 'Func'. myClassA.StaticFunc(); //Calls 'StaticFunc'. MyClass::StaticFunc(); //Calls 'StaticFunc'. MyClass::Func(); //Error: You can't call a non-static member-function without a class instance! return 0; } 

当你调用一个成员函数的时候,有一个叫做this的隐藏参数,它是一个指向调用该函数的类的实例的指针。 静态成员函数没有那个隐藏的参数…它们可以在没有类实例的情况下被调用,但是也不能访问类的非静态成员variables,因为它们没有“this”指针可以使用。 他们不被任何具体的类实例调用。

为了澄清这个问题,我宁愿将“静态”关键字的用法分为三种不同的forms:

(一个)。 variables

(B)。 function

(C)。 类的成员variables/函数

下面的每个子标题的解释如下:

(一)variables的“静态”关键字

这一点可能有点棘手,但如果解释和理解正确,这是非常简单的。

为了解释这个问题,首先知道variables的范围,持续时间和连接是非常有用的,没有这些variables总是难以通过关键词

1.范围 :确定文件中的哪个位置,variables是可访问的。 它可以有两种types:(一) 本地或区块范围 。 (二) 全球范围

2.持续时间 :确定何时创build和销毁variables。 它又有两种types:(i) 自动持续时间 (对于具有本地或块范围的variables)。 (ii) 静态持续时间 (对于具有全局范围的variables)。

3.链接 :确定是否可以在另一个文件中访问(或链接)一个variables。 再次(幸运地)它有两种types:(i) 内部联系 (对于具有区域范围和全局范围的variables)(ii) 外部联系 (对于仅具有全局范围的variables)

让我们来看下面的例子来更好地理解:

 //main file #include <iostream> int global_var1; //has global scope const global_var2(1.618); //has global scope int main() { //these variables are local to the block main. //they have automatic duration, ie, they are created when the main() is // executed and destroyed, when main goes out of scope int local_var1(23); const double local_var2(3.14); { /* this is yet another block, all variables declared within this block are have local scope limited within this block. */ // all variables declared within this block too have automatic duration, ie, /*they are created at the point of definition within this block, and destroyed as soon as this block ends */ char block_char1; int local_var1(32) //NOTE: this has been re-declared within the block, //it shadows the local_var1 declared outside std::cout << local_var1 <<"\n"; //prints 32 }//end of block //local_var1 declared inside goes out of scope std::cout << local_var1 << "\n"; //prints 23 global_var1 = 29; //global_var1 has been declared outside main (global scope) std::cout << global_var1 << "\n"; //prints 29 std::cout << global_var2 << "\n"; //prints 1.618 return 0; } //local_var1, local_var2 go out of scope as main ends //global_var1, global_var2 go out of scope as the program terminates //(in this case program ends with end of main, so both local and global //variable go out of scope together 

(读者请耐心等待:这是了解variables中各种情况下“静态”关键字的用法所需的基础)

现在来谈谈联动的概念。 当一个文件中定义的全局variables是要在另一个文件中使用时,variables的链接起着重要的作用。

全局variables的链接由关键字指定:(i) 静态的 ,(ii) extern

(现在你得到解释;-))

static关键字可以应用于局部范围和全局范围的variables,在这两种情况下,它们意味着不同的东西。 我将首先解释在全局variables的variables中使用'static'关键字(在这里我还阐明了关键字'extern'的用法),后面讲了那些局部variables的用法。

1.具有全局作用域的variables的静态关键字

全局variables具有静态持续时间,这意味着当它使用的特定代码块(例如main())结束时,它们不会超出范围。 根据链接的不同,它们只能在声明它们的同一个文件(对于静态全局variables)或者在文件之外(甚至在声明它们的文件之外)访问(externtypes全局variables)

在全局variables具有extern说明符的情况下,如果这个variables在被初始化的文件之外被访问,那么它必须在它被使用的文件中被前向声明,就像函数必须被转发声明它的定义是否与使用的文件不同。

相反,如果全局variables具有静态关键字,则不能在已声明的文件之外的文件中使用。

(请参阅下面的示例进行说明)

例如:

 //main2.cpp static int global_var3 = 23; /*static global variable, cannot be accessed in anyother file */ extern double global_var4 = 71; /*can be accessed outside this file linked to main2.cpp */ int main() { return 0; } 

main3.cpp

 //main3.cpp #include <iostream> int main() { extern int gloabl_var4; /*this variable refers to the gloabal_var4 defined in the main2.cpp file */ std::cout << global_var4 << "\n"; //prints 71; return 0; } 

现在c ++中的任何variables都可以是一个常量,也可以是一个非常量,对于每个“常量”,我们可以得到两种默认c ++链接的情况,如果没有指定的话:

(i) 如果一个全局variables是非常量的,它的连接是默认的extern ,也就是说,非常量全局variables可以通过使用extern关键字的前向声明在另一个.cpp文件中访问(换句话说,非常量全局variables有外部联系(当然是静态持续时间))。 在定义的原始文件中使用extern关键字也是多余的。 在这种情况下, 为了使外部文件无法访问非常量全局variables,请在variables的types之前使用说明符“static”

(ii) 如果一个全局variables是const的,它的链接默认是静态的 ,也就是说,一个const全局variables不能在一个文件中被访问,而不是被定义的地方(换句话说,const全局variables有内部链接当然))。 另外使用static关键字来防止在另一个文件中访问const全局variables是多余的。 这里, 要使一个const全局variables具有外部链接,请在variables的types之前使用说明符'extern'

以下是各种链接的全局范围variables的摘要

 //globalVariables1.cpp // defining uninitialized vairbles int globalVar1; // uninitialized global variable with external linkage static int globalVar2; // uninitialized global variable with internal linkage const int globalVar3; // error, since const variables must be initialized upon declaration const int globalVar4 = 23; //correct, but with static linkage (cannot be accessed outside the file where it has been declared*/ extern const double globalVar5 = 1.57; //this const variable ca be accessed outside the file where it has been declared 

接下来我们调查上述全局variables在不同文件中访问时的行为。

 //using_globalVariables1.cpp (eg for the usage of global variables above) // Forward declaration via extern keyword: extern int globalVar1; // correct since globalVar1 is not a const or static extern int globalVar2; //incorrect since globalVar2 has internal linkage extern const int globalVar4; /* incorrect since globalVar4 has no extern specifier, limited to internal linkage by default (static specifier for const variables) */ extern const double globalVar5; /*correct since in the previous file, it has extern specifier, no need to initialize the const variable here, since it has already been legitimately defined perviously */ 

2.本地范围variables的静态关键字

早些时候,我提到局部范围的variables具有自动持续时间,也就是说,当块进入时它们就会存在(这是一个正常的块,是一个function块),并在块结束时停止存在,长话短说, variables与本地范围有自动持续时间

如果静态指定符应用于块内的局部variables,则会将variables的持续时间从自动更改为静态

让我们看一个例子。

 //localVarDemo.cpp #include <iostream> int localNextID() { int tempID = 1; //tempID created here return tempID++; //copy of tempID returned and tempID incremented to 2 } //tempID destroyed here, hence value of tempID lost int newNextID() { static int newID = 0;//newID has static duration, with internal linkage return newID++; //copy of newID returned and newID incremented by 1 } //newID doesn't get destroyed here :-) int main() { int employeeID1 = nextID(); //employeeID1 = 1 int employeeID2 = nextID(); // employeeID2 = 1 again (not desired) int employeeID3 = newNextID(); //employeeID3 = 0; int employeeID4 = newNextID(); //employeeID4 = 1; int employeeID5 = newNextID(); //employeeID5 = 2; return 0; } 

这就结束了我对静态关键字应用于variables的解释。 pheww!

B.用于function的“静态”关键字

在function方面,静态关键字具有直接的意义。 这里指的是函数的链接通常所有在cpp文件中声明的函数默认都有外部链接,即一个文件中定义的函数可以通过前向声明在另一个cpp文件中使用。

在函数声明之前使用一个静态关键字来限制它与内部的链接 ,即一个静态函数不能在定义之外的文件中使用。

C. Staitc用于成员variables和类的函数的关键字

1.类的成员variables的“静态”关键字

我直接在这里开始一个例子

 #include <iostream> class DesignNumber { private: static int m_designNum; //design number int m_iteration; // number of iterations performed for the design public: DesignNumber() { } //default constructor int getItrNum() //get the iteration number of design { m_iteration = m_designNum++; return m_iteration; } static int m_anyVariable; //public static variable }; int DesignNumber::m_designNum = 0; // starting with design id = 0 // note : no need of static keyword here //causes compiler error if static keyword used int DesignNumber::m_anyNumber = 99; /* initialization of inclass public static member */ enter code here int main() { DesignNumber firstDesign, secondDesign, thirdDesign; std::cout << firstDesign.getItrNum() << "\n"; //prints 0 std::cout << secondDesign.getItrNum() << "\n"; //prints 1 std::cout << thirdDesign.getItrNum() << "\n"; //prints 2 std::cout << DesignNumber::m_anyNumber++ << "\n"; /* no object associated with m_anyNumber */ std::cout << DesignNumber::m_anyNumber++ << "\n"; //prints 100 std::cout << DesignNumber::m_anyNumber++ << "\n"; //prints 101 return 0; } 

在这个例子中,静态variablesm_designNum保留了它的值,并且这个单独的私有成员variables(因为它是静态的)被共享b / w对象types的所有variablesDesignNumber

与其他成员variables一样,类的静态成员variables也不与任何类对象关联,这是通过在main函数中打印anyNumber

类中的常量与非常量静态成员variables

(一)非常量类静态成员variables在前面的例子中,静态成员(公有和私有)都是非常量。 ISO标准禁止非常量静态成员在类中初始化。 因此,如前面的例子,它们必须在类定义之后初始化,但需要省略静态关键字

(ii)类的const-static成员variables很简单,并且遵循其他const成员variables初始化的约定,即一个类的const静态成员variables可以在声明点初始化,并且可以在结束时初始化有一点需要注意,关键字const在类定义之后被初始化时需要被添加到静态成员中。

然而,我会build议在声明点初始化const静态成员variables。 这符合标准的C ++约定,并使代码看起来更干净

有关类中静态成员variables的更多示例,请从learncpp.com查找以下链接:http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

2.类的成员函数的“静态”关键字

就像类的成员variables一样,是静态的,类的成员函数也是如此。 类的正常成员函数总是与类types的对象关联。 相比之下,类的静态成员函数不与类的任何对象关联,即它们没有*这个指针。

其次,由于类的静态成员函数没有this指针,因此可以使用主函数中的类名称和作用域parsing运算符(ClassName :: functionName();)

第三,一个类的静态成员函数只能访问一个类的静态成员variables,因为一个类的非静态成员variables必须属于一个类对象。

有关类中静态成员函数的更多示例,请从learncpp.com查找以下链接

http://www.learncpp.com/cpp-tutorial/812-static-member-functions/

我不是一个C程序员,所以我不能给你关于在C程序中使用static的信息,但是当涉及到面向对象的编程时,static基本上声明了一个variables,或者一个函数或类是相同的在整个程序的整个生命周期。 举个例子。

 class A { public: A(); ~A(); void somePublicMethod(); private: void somePrivateMethod(); }; 

当你在你的Main中实例化这个类时,你可以这样做。

 int main() { A a1; //do something on a1 A a2; //do something on a2 } 

这两个类实例是完全不同的,彼此独立运作。 但是如果你想这样重新创build类A的话。

 class A { public: A(); ~A(); void somePublicMethod(); static int x; private: void somePrivateMethod(); }; 

让我们再回到主线。

 int main() { A a1; a1.x = 1; //do something on a1 A a2; a2.x++; //do something on a2 } 

那么a1和a2将共享int x的相同副本,从而a1中x的任何操作都将直接影响a2中x的操作。 所以如果我这样做

 int main() { A a1; a1.x = 1; //do something on a1 cout << a1.x << endl; //this would be 1 A a2; a2.x++; cout << a2.x << endl; //this would be 2 //do something on a2 } 

类A的两个实例共享静态variables和函数。 希望这回答你的问题。 我对C有限的认识允许我说,将一个函数或variables定义为静态,意味着它只能被文件看到,函数或variables被定义为静态的。但是这最好由C语言家伙而不是我来完成。 C ++允许C和C ++方法将variables声明为静态,因为它完全向后兼容C.

这与局部variables是什么意思? 这是一个函数局部variables?

是 – 非全局,如函数局部variables。

因为当你声明一个局部静态的函数时,它只会被初始化一次,所以它第一次进入这个函数。

对。

它也只是谈论关于类成员的存储时间,那么它是非实例特定的,这也是一个静态的否定的属性? 或者是那个存储时间?

 class R { static int a; }; // << static lives for the duration of the program 

也就是说, R共享int R::aint R::a所有实例都不会被复制。

那么静态和文件范围的情况呢?

在适当的情况下,有效的是具有构造/析构函数的全局 – 在访问之前不会延迟初始化。

静态如何与variables的链接相关联?

对于本地函数来说,它是外部的。 访问:它可以访问的function(除非当然,你把它返回)。

对于一个class级来说,这是外部的。 访问:标准访问说明符适用(公共,受保护,私有)。

static也可以指定内部链接,取决于声明的位置(文件/命名空间)。

这整个静态关键字是彻头彻尾的混乱

它在C ++中的用途太多了。

有人可以澄清它的英语的不同用途,并告诉我什么时候初始化静态类成员?

它在main之前自动初始化,如果它被加载并且有一个构造函数。 That might sound like a good thing, but initialization order is largely beyond your control, so complex initialization becomes very difficult to maintain, and you want to minimize this — if you must have a static, then function local scales much better across libraries and projects. As far as data with static storage duration, you should try to minimize this design, particularly if mutable (global variables). Initialization 'time' also varies for a number of reasons — the loader and kernel have some tricks to minimize memory footprints and defer initialization, depending on the data in question.

Static Object: We can define class members static using static keyword. When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member.

A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present. We can't put it in the class definition but it can be initialized outside the class as done in the following example by redeclaring the static variable, using the scope resolution operator :: to identify which class it belongs to.

Let us try the following example to understand the concept of static data members:

 #include <iostream> using namespace std; class Box { public: static int objectCount; // Constructor definition Box(double l=2.0, double b=2.0, double h=2.0) { cout <<"Constructor called." << endl; length = l; breadth = b; height = h; // Increase every time object is created objectCount++; } double Volume() { return length * breadth * height; } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; // Initialize static member of class Box int Box::objectCount = 0; int main(void) { Box Box1(3.3, 1.2, 1.5); // Declare box1 Box Box2(8.5, 6.0, 2.0); // Declare box2 // Print total number of objects. cout << "Total objects: " << Box::objectCount << endl; return 0; } 

When the above code is compiled and executed, it produces the following result:

 Constructor called. Constructor called. Total objects: 2 

Static Function Members: By declaring a function member as static, you make it independent of any particular object of the class. A static member function can be called even if no objects of the class exist and the static functions are accessed using only the class name and the scope resolution operator ::.

A static member function can only access static data member, other static member functions and any other functions from outside the class.

Static member functions have a class scope and they do not have access to the this pointer of the class. You could use a static member function to determine whether some objects of the class have been created or not.

Let us try the following example to understand the concept of static function members:

 #include <iostream> using namespace std; class Box { public: static int objectCount; // Constructor definition Box(double l=2.0, double b=2.0, double h=2.0) { cout <<"Constructor called." << endl; length = l; breadth = b; height = h; // Increase every time object is created objectCount++; } double Volume() { return length * breadth * height; } static int getCount() { return objectCount; } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; // Initialize static member of class Box int Box::objectCount = 0; int main(void) { // Print total number of objects before creating object. cout << "Inital Stage Count: " << Box::getCount() << endl; Box Box1(3.3, 1.2, 1.5); // Declare box1 Box Box2(8.5, 6.0, 2.0); // Declare box2 // Print total number of objects after creating object. cout << "Final Stage Count: " << Box::getCount() << endl; return 0; } 

When the above code is compiled and executed, it produces the following result:

 Inital Stage Count: 0 Constructor called. Constructor called. Final Stage Count: 2