C++ 中的静态关键字 static

static在修饰不同的类型的时候有着不同的含义,一般我们可以用关键修饰:

  • 变量 【静态变量】
    • 函数中的变量 / 局部静态变量
    • 类的静态数据成员
  • 类的成员 【静态成员】
    • 静态对象
    • 类的静态成员函数

静态变量

1.函数中的静态变量:当一个函数中变量被修饰成静态的时候,它的生存期为整个函数的生存期。即使这个函数被调用了很多次,但是对改变量的内存分配只是一次,其值会保持上一次调用时候的值

//函数中的静态变量
#include 
#include 
using namespace std;

void demo()
{ 
    // static variable
    static int count = 0;
    cout << count << " ";
    // value is updated and will be carried to next functions calls
    count++;
}

int main()
{
    for (int i = 0; i < 5; i++)
        demo();
    return 0;
}

输出

0 1 2 3 4

局部作用域的静态变量的特点是:

  • 不会随着函数的每次调用产生一个副本
  • 也不会随着函数的返回而失效

2.类中的静态变量:当类中的某个成员变量被定义为静态的时候,它只被初始化一次,被类的对象所共享。不会因为多个对象而有多个副本,因此不能用构造函数去初始化

#include 
using namespace std;

 class GfG
{
  public :
    static int i;

    GfG()
    {
      // do noting
    }
};

int main()
{
  GfG obj1;
  GfG obj2;
  obj1.i = 2;
  obj2.i = 3;

  cout << obj1.i << obj2.i;
}

上述的程序试图给静态变量创造几个副本给不同的对象使用,但这样是不允许的。所以 类中的静态成员仅仅在类的定义中进行引用性声明,然后必须在命名空间作用域的某个地方使用类名限定定义性声明

#include 
using namespace std; 
  
class GfG 
{ 
public: 
    static int i; 
      
    GfG() 
    { 
        // Do nothing 
    }; 
}; 
// 类之外再加以定义
//用这种专门的形式为它们分配空间。
//非静态数据成员无须以此方式来定义,因为他们的空间是与他们所属对象的空间同时分配的  
int GfG::i = 1; 
  
int main() 
{ 
    GfG obj; 
    // prints value of i 
    cout << obj.i;  
}
  • 类的静态数据成员,在每个类中只有一个副本,由该类的所有对象共同维护和使用,从而实现了同一类的不同对象的之间的数据共享。

类的静态 【Static Members of Class】(暂且这样翻译)

1. 静态对象
首先比较下同一个类的 非静态对象和静态对象 例子

// CPP program to illustrate 
// when not using static keyword 
#include 
using namespace std; 
 
class GfG 
{ 
   int i; 
   public: 
       GfG() 
       { 
           i = 0; 
           cout << "Inside Constructor\n"; 
       } 
       ~GfG() 
       { 
           cout << "Inside Destructor\n"; 
       } 
}; 
 
int main() 
{ 
   int x = 0; 
   if (x==0) 
   { 
       GfG obj; 
   } 
   cout << "End of main\n"; 
} 
输出
// CPP program to illustrate 
// class objects as static 
#include 
using namespace std; 
  
class GfG 
{ 
    int i = 0; 
      
    public: 
    GfG() 
    { 
        i = 0; 
        cout << "Inside Constructor\n"; 
    } 
      
    ~GfG() 
    { 
        cout << "Inside Destructor\n"; 
    } 
}; 
  
int main() 
{ 
    int x = 0; 
    if (x==0) 
    { 
        static GfG obj; 
    } 
    cout << "End of main\n"; 
} 

输出

两者的区别在于析构函数什么时候被调用,静态对象拥有了和程序相同的生存期。

2.类的静态函数成员

  • 普通成员函数 : 调用必须通过对象名
  • 静态成员函数 :
    • 调用可以通过 类名 或者 对象名 【推荐类名,即使通过对象名,起作用的也只是对象的类型信息,与所使用的具体信息没有关系】
    • 静态成员函数 可以直接访问 该类的静态数据 和 函数成员,而访问非静态成员,必须通过对象名
include 
using namespace std;

class GfG
{
  public :
    static void printMsg()
    {
        cout << '' Welcome to GfG!'';
    }
};

int main()
{
    GfG::printMsg();
    // 直接通过类名来访问
}

总结

  • static 修饰
    • 普通变量 如函数中的变量 局部静态变量
    • 对象 静态对象
    • 类的数据成员 / 函数成员

问题 static 的作用

static全局变量 和 普通全局变量

  • 改变了作用域 (限制了其作用域)
    static 局部变量 和 普通局部变量
  • 改变了生存期
    static 函数 和 普通函数
  • static函数在内存中只有一份,普通在每个调用中维持一个拷贝



参考链接

  • https://www.geeksforgeeks.org/static-keyword-cpp/
  • https://www.cnblogs.com/stonejin/archive/2011/09/21/2183313.html
  • C++ 语言程序设计 郑莉

你可能感兴趣的:(C++ 中的静态关键字 static)