Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
static关键字及其在C++; >关键字>代码>静态/>代码>,它在C++中有多种含义,我觉得很困惑,我永远不会介意它实际上是如何工作的。< /P>_C++_Static - Fatal编程技术网

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
        }
    }