c++ static关键字一些事

static

static引入

考虑一个变量需要面向类的全部对象时,我们可以怎么来解决?
1、使用全局变量。但是全局变量会被非这个类的函数修改。
2、使用static声明类的静态变量。
所以,在 C++ 中,需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时,可将其定义为静态数据。

静态数据的存储

全局(静态)储存区:分为DATA和BSS段。
BSS:Block Started by Symbol,存放未初始化的全局变量的一块区域,或者是初始化为0。
DATA:存放已经初始化的变量的一块区域。
data类型的全局变量是即占文件空间,又占用运行时内存空间的。

static的声明和初始化

因为静态数据成员必须在程序一开始运行时就存在,所以不能被声明定义在函数里。 这样,就有三个可以对它进行空间分配的地方:
1、类的外部接口的头文件,也就是.h文件中。
2、类定义的内部实现,那里有类的成员函数定义。
3、应用程序main前的全局数据声明和定义处。

例每生成一个对象就+1.

#include <iostream>
using namespace std;

class A{
    
    
	public:
	static int a;	
	A();
	void p();
};

int A::a = 0;

A::A(){
    
    
	a++;
}
void A::p(){
    
    
	cout<<a<<endl;
}
int main()
{
    
    
	A a;
	a.p();
   return 0;
}

static的用法

  • 用于全局变量时,该变量作用域全局,存在静态储存区,别的文件不能通过extern访问

  • 用于局部变量时,作用域局部,但是存在静态储存区

  • 用于全局函数时,别的文件不能通过extern访问

  • 在c++中,static修饰的变量可以通过 类名.变量名 直接调用,static修饰的方法可以通过 类名.方法名直接调用。

结论 1:不能通过类名来调用类的非静态成员函数。
通过类的对象调用静态成员函数和非静态成员函数。

扫描二维码关注公众号,回复: 12896402 查看本文章
class Point  
{
    
      
public:   
    void init()  
    {
    
        
    }  
    static void output()  
    {
    
      
    }  
};  
void main()  
{
    
      
    Point::init(); //会报错 
    Point::output();  
}

结论 2:静态成员函数不能访问非静态成员,因为静态成员函数编译时就已经确认了地址,但是非静态成员还没,相当于没声明却使用了。

#include <stdio.h>  
class Point  
{
    
      
public:   
    void init()  
    {
    
        
    }  
    static void output()  
    {
    
      
        printf("%d\n", m_x);//会报错  
    }  
private:  
    int m_x;  
};  
void main()  
{
    
      
    Point pt;  
    pt.output();  
}

但是反过来,类的非静态成员函数却是可以调用静态成员函数的,因为此刻大家的地址都清晰了。

结论 3:类的静态成员必须先初始化再使用。

所以:
1)静态方法能不能引用非静态资源?不能,实例化对象的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。
2)静态方法里面能不能引用静态资源?可以,因为都是类初始化的时候加载的,大家相互都认识。
3)非静态方法里面能不能引用静态资源?可以,非静态方法就是实例方法,那是实例化对象之后才产生的,那么属于类的内容它都认识。

总结

  • 静态成员函数中不能调用非静态成员。
  • 非静态成员函数中可以调用静态成员。因为静态成员属于类本身,在类的对象产生之前就已经存在了,所以在非静态成员函数中是可以调用静态成员的。
  • 静态成员变量使用前必须先初始化(如 int MyClass::m_nNumber = 0;),否则会在 linker 时出错。

猜你喜欢

转载自blog.csdn.net/weixin_45146520/article/details/109577643