The static keyword and its various uses in C++
关键字EDOCX1 0是一个在C++中有多种含义的东西,我觉得很困惑,而且我永远不会介意它实际上是如何工作的。
据我所知,
C++标准对具有EDCOX1关键字0的类数据成员表示这一点:
3.7.1静态存储时间[基本.stc.静态]
3 The keyword static can be used to declare a local variable with static storage duration.
4 The keyword static applied to a class data member in a class definition gives the data member static storage duration.
局部变量是什么意思?这是函数局部变量吗?因为当您声明一个函数local为
它只讨论与类成员有关的存储持续时间,如果它不是特定于实例的,那么它也是
那么关于
1 All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these entities shall last for the duration of the program (3.6.2, 3.6.3)
整个
变量:(P)EDOCX1 0.Dimensions exist for the"lifetime"of the translation unit that it's defined in,and:(p)
- 如果在一个地名空间范围内(一.E.职能和类别的外部),这些功能和类别就不可能从任何其他外延单位获得。这是"内部链接"或"统计存储持续时间"。(Dont'do this in heads,it's just a terrible idea,you end up with a separate variable in each translation unit,which is crazy confusing)
- 如果这是一个函数中的一个变量,它就不能从函数的外部进入,而只是像任何其他局部变量。(This is the local they mentioned)
- class members have no restricted scope due to EDOCX1 penal 0,but can be addressed from the class as well as an instance(like EDOCX1 penal 2).[注:You can declar static members in a class,but they should usually still be defined in a translation unit(CPP file),and a s such,there's only one per class]
(P)Locations as Code:(p)字母名称(P)Before any function in a translation unit is executed(possibly after EDOCX1 original 3.Began execution),the variables with static storage duration(namespace scope)in that translation unit will be"constant initialized"(to EDOCX1 indicate 4,or zero otherwise),and they non-locals are"dynamically initialized"properly in the order they2.Are defined in the translation unit(for things like EDOCX1 penographic 5 nable that aren't EDOCX1 penographic 4).最后,功能——地方统计将是第一次执行"reaches"the line where they are declared.All EDOCX1 commonic 0 variables all destroyed in the reverse order of initialization.(p)(P)The easiest way to get all this right is to make all static variables that are not EDOCX1 universal 4.Initialized into function static locals,which make sure all of your statics/globals are initialized properly when you try to use them no matter what,thus preventing the static initialization order fiasco.(p)字母名称(P)当Spec says namespace-scope variables have"static storage duration"by default,they mean the"lifetime of the translation unit"bit,but that does not mean it can't be accessed outside of the file.(p)函数(P)意思是更多的Straightforward,EDOCX1的英文字母0被当作一个阶级成员的函数使用,只有极少的人被用于一个自由站立的函数。(p)(P)a Static member function differs from a regular member function in that it can be called without an instance of a class,and since it has no instance,it cannot access non-static members of the class.Static variables are useful when you want to have a function for a class that definitely absolutely does not refer to any instance members,or for managing EDOCX1 individual 0 member variables.(p)字母名称(P)a EDOCX1 o universal 0 free-function means that the function will not be referred to any other translation unit,and thus the linker can ignore it entirely.This has a small number of purposes:(p)
- Can be used in a CPP file to guarantee that the function is never used from any other file.
- 他们可以成为头领,每个文件都会有自己的功能。不要使用,因为注射不太可能是相同的东西。
- Speeds up link time by reducing work
- 它们可以在每一个转换单元中采用相同的名称,而它们可以做任何不同的事情。For instance,you could put a EDOCX1 penogical 12 welcome in each CPP file,and they could each all log in a different way.
静态存储持续时间意味着变量在程序的整个生命周期内都驻留在内存中的同一位置。
链接与此正交。
我认为这是最重要的区别。理解这一点,其余的,以及记住它,应该很容易(不是直接对@tony讲话,而是将来可能读到这篇文章的人)。
关键字
What does it mean with local variable? Is that a function local variable?
对。无论何时初始化变量(在第一次调用函数时,以及当执行路径到达声明点时),变量都将在程序生命周期内驻留在内存中的同一位置。在这种情况下,
Now what about the case with static and file scope? Are all global variables considered to have static storage duration by default?
是的,根据定义,所有全局都有静态存储持续时间(现在我们已经清除了这意味着什么)。但是名称空间范围的变量没有用
How does static relate to the linkage of a variable?
它提供命名空间范围的变量内部链接。它为成员和局部变量提供静态存储持续时间。
让我们进一步讨论所有这些:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // 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 class instances }; void foo() { static int x; //static storage duration - shared between calls } |
This whole static keyword is downright confusing
当然,除非你熟悉。:)为了避免在语言中添加新的关键词,委员会重新使用了这个词,imo,以达到这个效果-混淆。它用来表示不同的事物(我可以说,可能是相反的事物)。
为了澄清这个问题,我宁愿将"static"关键字的用法分为三种不同的形式:好的。
(a)变量好的。
(b)功能好的。
(c)。类的成员变量/函数好的。
对于每个子标题,解释如下:好的。
(a)变量的"static"关键字好的。
不过,如果解释和理解得当的话,这一点就不难了,这很简单。好的。
为了解释这一点,首先了解范围、持续时间是非常有用的以及变量之间的联系,没有这些联系,事情总是很难看清。通过staic关键字的模糊概念好的。
1。作用域:确定文件中可访问变量的位置。它可以有两种类型:(i)局部或块范围。(二)全球范围好的。
2。持续时间:确定何时创建和销毁变量。它有两种类型:(i)自动存储持续时间(对于具有局部或块范围的变量)。(ii)静态存储持续时间(对于具有全局范围或局部变量(在函数或代码块中)的变量,使用静态说明符)。好的。
三。链接:确定变量是否可以在另一个文件中被访问(或链接)。同样(幸运的是)它有两种类型:(i)内部连接(对于具有块范围和全局范围/文件范围/全局命名空间范围的变量)(ii)外部链接(对于仅具有全局范围/文件范围/全局命名空间范围的变量)好的。
让我们参考下面的一个示例,以更好地理解普通全局变量和局部变量(没有静态存储持续时间的局部变量):好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | //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, i.e, 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, i.e, /*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 <<" "; //prints 32 }//end of block //local_var1 declared inside goes out of scope std::cout << local_var1 <<" "; //prints 23 global_var1 = 29; //global_var1 has been declared outside main (global scope) std::cout << global_var1 <<" "; //prints 29 std::cout << global_var2 <<" "; //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 |
现在出现了连接的概念。当一个文件中定义的全局变量打算在另一个文件中使用时,该变量的链接起着重要作用。好的。
全局变量的链接由关键字指定:(i)静态,和(ii)外部好的。
(现在你得到解释;-)好的。
静态关键字可以应用于具有局部和全局范围的变量,在这两种情况下,它们的含义都不同。我将首先解释"static"关键字在具有全局范围的变量中的用法(在这里,我还将解释关键字"extern"的用法),然后解释具有局部范围的变量的用法。好的。
1。全局范围变量的静态关键字好的。
全局变量具有静态持续时间,这意味着当使用它的特定代码块(例如main())结束时,它们不会超出范围。根据链接的不同,它们只能在声明它们的同一个文件(对于静态全局变量)中访问,也可以在文件之外访问,甚至在声明它们的文件之外访问(外部类型全局变量)好的。
在全局变量具有外部说明符的情况下,如果在初始化该变量的文件之外访问该变量,则必须在使用该变量的文件中对其进行前向声明,就像函数的定义与使用该变量的文件不同时,必须对其进行前向声明一样。好的。
相反,如果全局变量具有static关键字,则不能在声明了该变量的文件之外使用该变量。好的。
(澄清见下例)好的。
如:好的。
1 2 3 4 5 | //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; } |
MIN 3.CPP好的。
1 2 3 4 5 6 7 8 9 10 11 12 | //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 <<" "; //prints 71; return 0; } |
现在C++中的任何变量既可以是const也可以是非const,对于每个"const",我们得到两个缺省C++链接的情况,如果没有指定的话:好的。
(i)如果一个全局变量是非常量,默认情况下它的链接是外部的,也就是说,可以通过使用extern关键字的forward声明在另一个.cpp文件中访问非常量全局变量(换句话说,非常量全局变量具有外部链接(当然是静态持续时间))。另外,在定义了extern关键字的原始文件中使用extern关键字也是多余的。在这种情况下,要使外部文件无法访问非常量全局变量,请在变量类型之前使用说明符"static"。好的。
(i i)如果一个全局变量是常量,默认情况下它的链接是静态的,即常量全局变量不能在一个文件中访问,而不是在定义它的位置(换句话说,常量全局变量有内部链接(当然是静态持续时间))。另外,使用static关键字防止在另一个文件中访问const全局变量也是多余的。这里,要使常量全局变量具有外部链接,请在变量类型之前使用说明符"extern"好的。
下面是具有各种链接的全局范围变量的摘要好的。
1 2 3 4 5 6 7 8 | //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 |
接下来,我们研究在不同的文件中访问时,上述全局变量的行为。好的。
1 2 3 4 5 6 7 8 9 10 11 12 | //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。具有局部作用域的变量的静态关键字好的。
前面,我提到了具有局部作用域的变量具有自动持续时间,即当块被输入(无论它是普通块,还是功能块)时,变量就出现了;当块结束时,变量不再存在;长话短说,具有局部作用域的变量具有自动持续时间,自动持续时间变量(和对象)没有链接。它们在代码块外不可见。好的。
如果静态说明符应用于块内的局部变量,则它会将变量的持续时间从自动更改为静态,其生存时间是程序的整个持续时间,这意味着它具有固定的内存位置,并且其值仅在程序启动前初始化一次,如cpp reference中所述(初始化应为不要与作业混淆)好的。
让我们来看一个例子。好的。型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | //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; } |
这就结束了我对应用于变量的静态关键字的解释。啊!!!好的。型
b.用于函数的"static"关键字好的。型
在函数方面,静态关键字有一个直接的含义。在这里,它指的是函数的链接通常,cpp文件中声明的所有函数默认都具有外部链接,即一个文件中定义的函数可以通过转发声明在另一个cpp文件中使用。好的。型
在函数声明前使用静态关键字将其链接限制为内部,即静态函数不能在其定义之外的文件中使用。好的。型
c.用于成员变量和类函数的staitc关键字好的。型
1.'类的成员变量的"static"关键字好的。型
我直接从一个例子开始好的。型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #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_anyNumber; //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() <<" "; //prints 0 std::cout << secondDesign.getItrNum() <<" "; //prints 1 std::cout << thirdDesign.getItrNum() <<" "; //prints 2 std::cout << DesignNumber::m_anyNumber++ <<" "; /* no object associated with m_anyNumber */ std::cout << DesignNumber::m_anyNumber++ <<" "; //prints 100 std::cout << DesignNumber::m_anyNumber++ <<" "; //prints 101 return 0; } |
号
在本例中,静态变量m_designnum保留其值,而这个单独的私有成员变量(因为它是静态的)与对象类型designnumber的所有变量b/w共享。好的。型
与其他成员变量一样,类的静态成员变量不与任何类对象关联,这可以通过在主函数中打印任意数字来演示。好的。型
类中的常量与非常量静态成员变量好的。型
(i)非常量类静态成员变量在前面的示例中,静态成员(公共成员和私有成员)都是非常量。ISO标准禁止在类中初始化非常量静态成员。因此,与前面的示例一样,它们必须在类定义之后进行初始化,注意需要省略静态关键字。好的。型
(ii)类的常量静态成员变量这很简单,并且符合其他const成员变量初始化的约定,即类的const静态成员变量可以在声明点进行初始化,并且可以在类声明的末尾进行初始化,其中一个警告是,关键字const需要添加到静态成员中。在类定义之后初始化。好的。型
但是,我建议在声明点初始化const静态成员变量。这符合标准的C++约定,使代码看起来更干净。好的。型
有关类中静态成员变量的更多示例,请查看learncpp.com中的以下链接http://www.learncpp.com/cpp-tutorial/811-static-member-variables/静态成员变量/好的。型
2.'类的成员函数的"static"关键字好的。型
就像类的成员变量可以是静态的一样,类的成员函数也可以是静态的。类的普通成员函数总是与类类型的对象相关联。相反,类的静态成员函数与类的任何对象都没有关联,即它们没有*这个指针。好的。
其次,由于类的静态成员函数没有*这个指针,所以可以使用主函数中的类名和作用域解析操作符(class name::functionname();)调用它们。好的。
第三,类的静态成员函数只能访问类的静态成员变量,因为类的非静态成员变量必须属于类对象。好的。
有关类中静态成员函数的更多示例,请查看learncpp.com中的以下链接好的。
http://www.learncpp.com/cpp-tutorial/812-static-member-functions/好的。好啊。
其实很简单。如果在函数的作用域中将变量声明为静态变量,则在对该函数的连续调用之间保留该变量的值。所以:
1 2 3 4 5 6 7 8 9 10 11 12 | int myFun() { static int i=5; i++; return i; } int main() { printf("%d", myFun()); printf("%d", myFun()); printf("%d", myFun()); } |
将显示
对于静态成员,它们在类的实例之间保留其值。所以下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 | struct A { static int a; }; int main() { A first; A second; first.a = 3; second.a = 4; printf("%d", first.a); } |
将打印4,因为第一个.a和第二个.a基本上是相同的变量。关于初始化,请参见此问题。
静态变量在类的每个实例之间共享,而不是每个类都有自己的变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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",您可以在类外部访问它,如下所示:
1 | MyClass::myStaticVar //Assuming it's publicly accessible. |
当在函数内部用作局部变量(而不是类成员变量)时,static关键字会执行不同的操作。它允许您创建一个持久变量,而不提供全局范围。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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; } |
就持久性而言,它是一个全局变量…但在范围/可访问性方面不具有全局性。
您还可以拥有静态成员函数。静态函数基本上是非成员函数,但在类名的命名空间内,并且具有对类成员的私有访问权。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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"的隐藏参数,它是指向调用该函数的类实例的指针。静态成员函数没有该隐藏参数…它们在没有类实例的情况下是可调用的,但也不能访问类的非静态成员变量,因为它们没有"this"指针。没有在任何特定的类实例上调用它们。
当你在
a.cppP></
1 2 3 4 5 6 | static int x = 7; void printax() { cout <<"from a.cpp: x=" << x << endl; } |
b.cppP></
1 2 3 4 5 6 | static int x = 9; void printbx() { cout <<"from b.cpp: x=" << x << endl; } |
main.cpp:P></
1 2 3 4 5 6 7 | int main(int, char **) { printax(); // Will print 7 printbx(); // Will print 9 return 0; } |
for a local variable变量的均值,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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; } |
for class variables,that there is only a en means of that variable that is单审级的构件,要求银行共享。在线depending permissions,can be from the variable accessed using its the舱外全层次的名称。P></
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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; }; |
标记不
a.cppP></
1 2 3 4 5 | 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.cppP></
1 2 3 4 5 | 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; } |
for them as类的数据成员,形成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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; } |
静态对象:我们可以使用static关键字定义类成员static。当我们将类的成员声明为静态时,这意味着无论创建了多少个类对象,静态成员都只有一个副本。
静态成员由类的所有对象共享。如果不存在其他初始化,则在创建第一个对象时,所有静态数据都初始化为零。我们不能将它放入类定义中,但是可以像下面的示例中那样在类外部初始化它,方法是使用范围解析操作符::重新声明静态变量,以标识它属于哪个类。
让我们尝试以下示例来理解静态数据成员的概念:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #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; } |
在编译和执行上述代码时,会产生以下结果:
1 2 3 | Constructor called. Constructor called. Total objects: 2 |
静态函数成员:通过将函数成员声明为静态的,可以使它独立于类的任何特定对象。即使不存在类的对象,并且仅使用类名和作用域解析运算符::访问静态函数,也可以调用静态成员函数。
静态成员函数只能从类外部访问静态数据成员、其他静态成员函数和任何其他函数。
静态成员函数有一个类作用域,它们不能访问类的这个指针。可以使用静态成员函数来确定类的某些对象是否已创建。
让我们尝试下面的例子来理解静态函数成员的概念:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #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; } |
在编译和执行上述代码时,会产生以下结果:
1 2 3 4 | Inital Stage Count: 0 Constructor called. Constructor called. Final Stage Count: 2 |
What does it mean with local variable? Is that a function local variable?
-不-是全球局部变量函数,such as a。P></
Because there's also that when you declare a function local as static that it is only initialized once, the first time it enters this function.
好的。P></
It also only talks about storage duration with regards to class members, what about it being non instance specific, that's also a property of static no? Or is that storage duration?
1 | class R { static int a; }; // << static lives for the duration of the program |
that is to say"的情况下,
Now what about the case with static and file scope?
在全球effectively which has构造函数/ destructor在适当的地方initialization is not until -接入延迟。P></
How does static relate to the linkage of a variable?
function is for a local,和EN。接入:它(除非accessible to the function of You),回车)。P></
is for a class,它的外部。访问说明符(适用:标准接入保护,公共,私人)。P></
This whole static keyword is downright confusing
它有太多用途的C + +。P></
can someone clarify the different uses for it English and also tell me when to initialize a static class member?
这是
我不是一个C程序员,所以我不能给你关于静态在C程序中的用法的信息,但是当涉及面向对象编程时,静态基本上声明了一个变量、一个函数或一个类在程序的整个生命周期中是相同的。举个例子。
1 2 3 4 5 6 7 8 9 | class A { public: A(); ~A(); void somePublicMethod(); private: void somePrivateMethod(); }; |
当您在主类中实例化这个类时,您会这样做。
1 2 3 4 5 6 7 | int main() { A a1; //do something on a1 A a2; //do something on a2 } |
这两个类实例完全不同,并且彼此独立操作。但如果你要重现这样的A类。
1 2 3 4 5 6 7 8 9 10 | class A { public: A(); ~A(); void somePublicMethod(); static int x; private: void somePrivateMethod(); }; |
我们再回到主管道。
1 2 3 4 5 6 7 8 9 | 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的操作。所以如果我要这么做的话
1 2 3 4 5 6 7 8 9 10 11 | 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的两个实例共享静态变量和函数。希望这能回答你的问题。我有限的C知识使我可以说,将一个函数或变量定义为静态的意味着它只对该函数或变量定义为静态的文件可见。但最好是由一个狱警而不是我来回答。C++允许C和C++方式声明变量是静态的,因为它完全兼容C。