关闭

static作用

106人阅读 评论(0) 收藏 举报
分类:
c++primer中的static解释
static表示静态,可以修饰变量, 函数,类。
static修饰一个变量,可表示该变量的存储持续性,以及连接性。
(存储持续性分为四种:自动存储持续性:在函数定义中声明的变量(包括函数参数)的存储持续性为自动的,他们在程序开始执行其所属的函数或代码块时被创建,在执行完函数或代码块时,使用的内存被释放。静态存储持续性:在函数定义外定义的变量和使用关键字static定义的变量的存储持续性都为静态,他们在程序整个运行过程中都存在。线程存储持续性:使用关键字Thread_local声明的。动态存储持续性:用new运算符分配的内存将一直存在,使用delete或者程序结束时,才结束)。
static修饰的变量都是静态存储持续性
在函数定义外定义的变量叫做外部变量:为静态持续性,外部链接性,可以在所有文件中进行使用。c++有单定义规则,变量只能有一次定义。此时在多个文件中,只能定义一次外部变量,其他文件里面如果要使用,加上extern
例如:一个文件中定义 int a =10;另一个文件中用extern int a;此时就可以使用a了。若一个文件中多次使用这种定义,都是相通的,所以其他都可以省略。
在函数外定义static变量叫静态全局变量:为静态持续性,内部连接性,只可以在当前文件中进行使用,即其他文件中再定义重名的外部变量是允许的。
在函数中定义static变量叫静态局部变量:为静态持续性,无连接性。该变量只在该代码块中可用,但它在该代码块不处于活动状态时仍然存在,不会清零。因此在两次函数调用之间,静态局部变量的值可以进行递加。如果初始化了局部变量,那程序只在启动时运行一次初始化。


静态变量与非静态变量的区别如下:
1.内存分配
静态变量在应用程序初始化时,就存在于内存当中,直到它所在的类的程序运行结束时才消亡;
而非静态变量需要被实例化后才会分配内存。
2.生存周期
静态变量生存周期为应用程序的存在周期;
非静态变量的存在周期取决于实例化的类的存在周期。
3.调用方式
静态变量只能通过“类.静态变量名”调用,类的实例不能调用;
非静态变量当该变量所在的类被实例化后,可通过实例化的类名直接访问。
4.共享方式
静态变量是全局变量,被所有类的实例对象共享,即一个实例的改变了静态变量的值,其他同类的实例读到的就是变化后的值;
非静态变量是局部变量,不共享的。
5.访问方式
静态成员不能访问非静态成员;
非静态成员可以访问静态成员。 


静态函数:c++不允许一个函数中定义另外一个函数,所以所有函数的存储持续性都自动为静态的。即在整个程序执行期间都是一直存在的。默认情况下,函数的链接性为外部的,即在文件中共享。一般调用需要extern,但是程序自动加载,不需手动加载。也可以使用static,将函数设置为内部的。

静态函数是属于类所有,非静态函数属于对象所有
如果一个类里面有一个静态函数,一个非静态函数
你实例出一个对象来就可以访问里面的非静态函数
不实例对象,单单类名.成员这种样子才能访问静态函数

也没什么区别,如果你实例一个对象的话,就是只有这个对象独立使用这个非静态函数,可是非静态函数是类使用的,也就是公用的差不多

就像是一个是公用厕所,一个是家用厕所一样
静态函数主要是用来访问静态成员,不能直接访问类的非静态成员; 而非静态函数既可以访问静态成员,也可以访问费静态成员。 
c++中没有静态类,java,c#中有静态类

静态类只用于包含静态成员的类型,不能进行实例化。

静态类的特性是防止继承,防止外部进行new操作。

静态类相当于一个sealed abstract类。  举例如下:

1
2
3
4
5
6
7
8
static class MyUtility 
    public const int data; 
    public static void Foo() 
    
        ... 
    
}

静态类的几个注意点: 1、静态类不能有实例构造器;  2、静态类不能有任何实例成员;  3、静态类不能使用abstract或sealed修饰符;  4、静态类默认继承自System.Object根类,不能显式指定任何其他基类;  5、静态类不能指定任何接口实现; 6、静态类的成员不能有protected或protected internal访问保护修饰符。


静态成员如果有n个同类的对象,那么每一个对象都分别有自己的数据成员,不同对象的数据成员各自有值,互不相干。但是有时人们希望有某一个或几个数据成员为所有对象所共有。这样可以实现数据共享。

在前面介绍过全局变量能够实现数据共享。

如果在一个程序文件中有多个函数,在每一个函数中都可以改变全局变量的值,全局变量的值为各函数共享。但是用全局变量的安全性得不到保证,由于在各处都可以自由地修改全局变量的值,很有可能偶一失误,全局变量的值就被修改,导致程序的失败。因此在实际工作中很少使用全局变量。

如果想在同类的多个对象之间实现数据共享,也不要用全局对象,可以用静态的数据成员。

静态数据成员是一种特殊的数据成员。它以关键字static开头。例如
class Box
{
   public :
   int volume( );
   private :
   static int height; //把height定义为静态的数据成员
   int width; int length;
};
如果希望各对象中的height的值是一样的,就可以把它定义为静态数据成员,这样它就为各对象所共有,而不只属于某个对象的成员,所有对象都可以引用它。

静态的数据成员在内存中只占一份空间。每个对象都可以引用这个静态数据成员。静态数据成员的值对所有对象都是一样的。如果改变它的值,则在各对象中这个数据成员的值都同时改变了。这样可以节约空间,提高效率。

关于静态数据成员的几点说明:
  1. 在前面我们已经强调: 如果只声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,才为对象的数据成员分配空间。

    但是静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。静态数据成员是在所有对象之外单独开辟空间。只要在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用。在一个类中可以有一个或多个静态数据成员,所有的对象共享这些静态数据成员,都可以引用它。
  2. 我们已经知道了静态变量的概念: 如果在一个函数中定义了静态变量,在函数结束时该静态变量并不释放,仍然存在并保留其值。
    现在讨论的静态数据成员也是类似的,它不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。静态数据成员是在程序编译时被分配空间的,到程序结束时才释放空间。
  3. 静态数据成员可以初始化,但只能在类体外进行初始化。如
       int Box::height=10; //表示对Box类中的数据成员初始化
    其一般形式为
        数据类型类名::静态数据成员名=初值;

    不必在初始化语句中加static。

    注意: 不能用参数初始化表对静态数据成员初始化。如在定义Box类中这样定义构造函数是错误的:
       Box(int h,int w,int len):height(h){ } //错误,height是静态数据成员
    如果未对静态数据成员赋初值,则编译系统会自动赋予初值0。
  4. 静态数据成员既可以通过对象名引用,也可以通过类名来引用。请观察下面的程序。
    例9.10 引用静态数据成员。
    cout<<a.height<<endl; 通过对象名a引用静态数据成员
    cout<<b.height<<endl; 通过对象名b引用静态数据成员
    cout<<box::height<<endl; 通过类名引用静态数据成员
    cout<<a.volume( )<<endl;="" 调用volume函数,计算体积,输出结果}
    上面3个输出语句的输出结果相同(都是10)。这就验证了所有对象的静态数据成员实际上是同一个数据成员。

    请注意: 在上面的程序中将height定义为公用的静态数据成员,所以在类外可以直接引用。可以看到在类外可以通过对象名引用公用的静态数据成员,也可以通过类名引用静态数据成员。即使没有定义类对象,也可以通过类名引用静态数据成员。这说明静态数据成员并不是属于对象的,而是属于类的,但类的对象可以引用它。

    如果静态数据成员被定义为私有的,则不能在类外直接引用,而必须通过公用的成员函数引用。
  5. 有了静态数据成员,各对象之间的数据有了沟通的渠道,实现数据共享,因此可以不使用全局变量。
    全局变量破坏了封装的原则,不符合面向对象程序的要求。但是也要注意公用静态数据成员与全局变量的不同,静态数据成员的作用域只限于定义该类的作用域内(如果是在一个函数中定义类,那么其中静态数据成员的作用域就是此函数内)。在此作用域内,可以通过类名和域运算符“::”引用静态数据成员,而不论类对象是否存在。
c++primer中的static解释
static表示静态,可以修饰变量, 函数,类。
static修饰一个变量,可表示该变量的存储持续性,以及连接性。
(存储持续性分为四种:自动存储持续性:在函数定义中声明的变量(包括函数参数)的存储持续性为自动的,他们在程序开始执行其所属的函数或代码块时被创建,在执行完函数或代码块时,使用的内存被释放。静态存储持续性:在函数定义外定义的变量和使用关键字static定义的变量的存储持续性都为静态,他们在程序整个运行过程中都存在。线程存储持续性:使用关键字Thread_local声明的。动态存储持续性:用new运算符分配的内存将一直存在,使用delete或者程序结束时,才结束)。
static修饰的变量都是静态存储持续性
在函数定义外定义的变量叫做外部变量:为静态持续性,外部链接性,可以在所有文件中进行使用。c++有单定义规则,变量只能有一次定义。此时在多个文件中,只能定义一次外部变量,其他文件里面如果要使用,加上extern
例如:一个文件中定义 int a =10;另一个文件中用extern int a;此时就可以使用a了。若一个文件中多次使用这种定义,都是相通的,所以其他都可以省略。
在函数外定义static变量叫静态全局变量:为静态持续性,内部连接性,只可以在当前文件中进行使用,即其他文件中再定义重名的外部变量是允许的。
在函数中定义static变量叫静态局部变量:为静态持续性,无连接性。该变量只在该代码块中可用,但它在该代码块不处于活动状态时仍然存在,不会清零。因此在两次函数调用之间,静态局部变量的值可以进行递加。如果初始化了局部变量,那程序只在启动时运行一次初始化。
静态变量与非静态变量的区别如下:
1.内存分配
静态变量在应用程序初始化时,就存在于内存当中,直到它所在的类的程序运行结束时才消亡;
而非静态变量需要被实例化后才会分配内存。
2.生存周期
静态变量生存周期为应用程序的存在周期;
非静态变量的存在周期取决于实例化的类的存在周期。
3.调用方式
静态变量只能通过“类.静态变量名”调用,类的实例不能调用;
非静态变量当该变量所在的类被实例化后,可通过实例化的类名直接访问。
4.共享方式
静态变量是全局变量,被所有类的实例对象共享,即一个实例的改变了静态变量的值,其他同类的实例读到的就是变化后的值;
非静态变量是局部变量,不共享的。
5.访问方式
静态成员不能访问非静态成员;
非静态成员可以访问静态成员。 


静态函数:c++不允许一个函数中定义另外一个函数,所以所有函数的存储持续性都自动为静态的。即在整个程序执行期间都是一直存在的。默认情况下,函数的链接性为外部的,即在文件中共享。一般调用需要extern,但是程序自动加载,不需手动加载。也可以使用static,将函数设置为内部的。

静态函数是属于类所有,非静态函数属于对象所有
如果一个类里面有一个静态函数,一个非静态函数
你实例出一个对象来就可以访问里面的非静态函数
不实例对象,单单类名.成员这种样子才能访问静态函数

也没什么区别,如果你实例一个对象的话,就是只有这个对象独立使用这个非静态函数,可是非静态函数是类使用的,也就是公用的差不多

就像是一个是公用厕所,一个是家用厕所一样
静态函数主要是用来访问静态成员,不能直接访问类的非静态成员; 而非静态函数既可以访问静态成员,也可以访问费静态成员。 
c++中没有静态类,java,c#中有静态类

静态类只用于包含静态成员的类型,不能进行实例化。

静态类的特性是防止继承,防止外部进行new操作。

静态类相当于一个sealed abstract类。  举例如下:

1
2
3
4
5
6
7
8
static class MyUtility 
    public const int data; 
    public static void Foo() 
    
        ... 
    
}

静态类的几个注意点: 1、静态类不能有实例构造器;  2、静态类不能有任何实例成员;  3、静态类不能使用abstract或sealed修饰符;  4、静态类默认继承自System.Object根类,不能显式指定任何其他基类;  5、静态类不能指定任何接口实现; 6、静态类的成员不能有protected或protected internal访问保护修饰符。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21289次
    • 积分:1363
    • 等级:
    • 排名:千里之外
    • 原创:122篇
    • 转载:5篇
    • 译文:0篇
    • 评论:4条
    最新评论