static关键字及其在C++; >关键字>代码>静态/>代码>,它在C++中有多种含义,我觉得很困惑,我永远不会介意它实际上是如何工作的。< /P>
据我所知,有一个static关键字及其在C++; >关键字>代码>静态/>代码>,它在C++中有多种含义,我觉得很困惑,我永远不会介意它实际上是如何工作的。< /P>,c++,static,C++,Static,据我所知,有一个静态存储持续时间,这意味着在全局的情况下,它将持续整个程序的生命周期,但当你谈论局部时,它意味着默认情况下初始化为零 C++标准对类数据成员用关键字静态< /代码>: 3.7.1静态存储持续时间[basic.stc.Static] 3关键字static可用于声明具有静态存储持续时间的局部变量 4应用于类定义中的类数据成员的关键字static给出了该数据成员的静态存储持续时间 局部变量是什么意思?这是一个局部变量函数吗?因为还有一个问题,当您将函数本地声明为static时,它只初
静态存储持续时间,这意味着在全局的情况下,它将持续整个程序的生命周期,但当你谈论局部时,它意味着默认情况下初始化为零
C++标准对类数据成员用关键字<代码>静态< /代码>:
3.7.1静态存储持续时间[basic.stc.Static]
3关键字static可用于声明具有静态存储持续时间的局部变量
4应用于类定义中的类数据成员的关键字static给出了该数据成员的静态存储持续时间
局部变量是什么意思?这是一个局部变量函数吗?因为还有一个问题,当您将函数本地声明为static
时,它只初始化一次,第一次进入这个函数时
它还只讨论了类成员的存储持续时间,它是非实例特定的,这也是static
no的一个属性吗?或者是存储时间
现在关于静态和文件范围的情况如何?默认情况下,是否所有全局变量都被视为具有静态存储持续时间?以下(第3.7.1节)似乎表明了这一点:
1所有没有动态存储持续时间、没有线程存储持续时间和非本地的变量都有静态存储持续时间。这些实体的存储应在项目期间持续(3.6.2、3.6.3)
static
如何与变量的链接相关
整个static
关键字完全让人困惑,有人能用英语解释一下它的不同用法吗?还有人能告诉我什么时候初始化static
类成员吗?静态变量在类的每个实例之间共享,而不是每个类都有自己的变量
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.
当在函数中用作局部变量(而不是类成员变量)时,static关键字会做一些不同的事情。它允许您创建一个持久变量,而无需提供全局范围
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;
}
调用成员函数时,有一个名为“this”的隐藏参数,它是指向调用该函数的类实例的指针。
静态成员函数没有该隐藏参数。。。它们可以在没有类实例的情况下调用,但也不能访问类的非静态成员变量,因为它们没有可使用的“this”指针。没有对任何特定类实例调用它们。变量:
静态
变量在定义的翻译单元的“生命周期”内存在,并且:
- 如果它位于名称空间范围内(即函数和类之外),则不能从任何其他转换单元访问它。这称为“内部链接”或“静态存储持续时间”。(除了
constexpr
之外,不要在标题中执行此操作。任何其他操作都会导致每个翻译单元中都有一个单独的变量,这让人非常困惑)
- 如果它是函数中的一个变量,就不能像其他局部变量一样从函数外部访问它。(这是他们提到的当地人)
- 由于
静态
,类成员没有受限制的作用域,但可以从类和实例(如std::string::npos
)中寻址。[注意:您可以在类中声明静态成员,但它们通常仍应在翻译单元(cpp文件)中定义,因此,每个类只有一个]
代码为的位置:
static std::string namespaceScope = "Hello";
void foo() {
static std::string functionScope= "World";
}
struct A {
static std::string classScope = "!";
};
在执行翻译单元中的任何函数之前(可能在main
开始执行之后),该翻译单元中具有静态存储持续时间(命名空间范围)的变量将被“常量初始化”(在可能的情况下为constexpr
,否则为零),然后非局部变量将被“动态初始化”按照翻译单元中定义的顺序正确排列(对于不是constexpr
的std::string=“HI”
)。最后,函数本地静态将在执行第一次“到达”声明它们的行时初始化。所有静态
变量均按与初始化相反的顺序销毁
最简单的方法是将所有非constexpr
的静态变量初始化为函数静态局部变量,这样可以确保在尝试使用静态/全局变量时,无论发生什么情况,所有静态/全局变量都已正确初始化,从而防止出现错误
请小心,因为当规范说名称空间范围变量在默认情况下具有“静态存储持续时间”时,它们表示“转换单元的生存期”位,但这并不意味着不能在文件之外访问它
功能
更直接的是,静态
通常用作类成员函数,很少用于独立函数
静态成员函数与常规成员函数的不同之处在于,它可以在没有类实例的情况下调用,并且由于它没有实例,因此无法访问类的非静态成员。当您想要为一个绝对不引用任何实例成员的类创建函数,或者管理Static
成员变量时,静态变量非常有用
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
}
静态
自由函数意味着该函数不会被任何其他transla引用
T& get_global() {
static T global = initial_value();
return global;
}
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
}
class A
{
public:
A();
~A();
void somePublicMethod();
private:
void somePrivateMethod();
};
int main()
{
A a1;
//do something on a1
A a2;
//do something on a2
}
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
}
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
}
//
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
}
int myFun()
{
static int i=5;
i++;
return i;
}
int main()
{
printf("%d", myFun());
printf("%d", myFun());
printf("%d", myFun());
}
struct A
{
static int a;
};
int main()
{
A first;
A second;
first.a = 3;
second.a = 4;
printf("%d", first.a);
}
static int x = 7;
void printax()
{
cout << "from a.cpp: x=" << x << endl;
}
static int x = 9;
void printbx()
{
cout << "from b.cpp: x=" << x << endl;
}
int main(int, char **)
{
printax(); // Will print 7
printbx(); // Will print 9
return 0;
}
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;
}
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 void printfilename()
{ // this is the printfilename from a.cpp -
// it can't be accessed from any other file
cout << "this is a.cpp" << endl;
}
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;
}
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;
}
class R { static int a; }; // << static lives for the duration of the program
#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;
}
Constructor called.
Constructor called.
Total objects: 2
#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;
}
Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2
//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 <<"\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
//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
#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;
}
//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
//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 */
//localVarDemo1.cpp
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 = localNextID(); //employeeID1 = 1
int employeeID2 = localNextID(); // employeeID2 = 1 again (not desired)
int employeeID3 = newNextID(); //employeeID3 = 0;
int employeeID4 = newNextID(); //employeeID4 = 1;
int employeeID5 = newNextID(); //employeeID5 = 2;
return 0;
}
//localVarDemo2.cpp
//static storage duration with global scope
//note this variable can be accessed from outside the file
//in a different compilation unit by using `extern` specifier
//which might not be desirable for certain use case.
static int globalId = 0;
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()
{
//since globalId is accessible we use it directly
const int globalEmployee1Id = globalId++; //globalEmployeeId1 = 0;
const int globalEmployee2Id = globalId++; //globalEmployeeId1 = 1;
//const int employeeID1 = newID++; //this will lead to compilation error since newID++ is not accessible direcly.
int employeeID2 = newNextID(); //employeeID3 = 0;
int employeeID2 = newNextID(); //employeeID3 = 1;
return 0;
}
//localVarDemo3.cpp
int main()
{
{
const static int static_local_scoped_variable {99};
}//static_local_scoped_variable goes out of scope
//the line below causes compilation error
//do_something is an arbitrary function
do_something(static_local_scoped_variable);
return 0;
}
#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() << "\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;
}
//global member
int i=10;
int main(){
[]{std::cout << i;}();
//prints 10
}
int main(){
int i{11};
[]{std::cout << i;}(); //compiler error
[i]{std::cout << i;}(); //capture by value; correct
//or
[&i]{std::cout << i;}(); //capture by reference; correct
}
int main(){
static int i{12};
[]{std::cout << i;}(); //prints 12
{
[]{std::cout << i;}();//also prints 12
}
}