【总结】C++与C#中的static静态修饰符

重点

  1. 静态类(sealed+abstract)
  2. 静态构造函数(无参,无限制符,自动执行一次)
  3. 静态变量(类级别,实例无关,静态存储区中)
  4. 静态方法(不能被重写)
  5. 静态局部变量(始终存在)

静态本质是实例无关的,表示不会修改实例的

C++

静态成员变量

  • 静态成员 的内存只被分配一次,会一直存在于程序的整个生命周期中
  • 如果要将静态成员类内初始化,那么该变量需要声明为const常量
  • int class :: c = 10;      static数据成员可以在类外定义和初始化,也可以在函数中赋值。可以直接由 class::member 访问,但是不能用 .访问

静态成员函数

  • 成员函数、静态成员函数、虚函数

    在c++中类的成员函数都是保存在静态存储区中的,都是通过函数地址来访问。

  • 不能调用non-static函数,但是可以通过引用传递间接调用
  • 为什么静态成员函数不能是const?const修饰符用于表示函数不能修改成员变量的值,该函数必须是含有this指针的类成员函数,函数调用方式为thiscall

而类中的static函数本质上是全局函数,不能访问非静态成员,const函数表明不会修改实例成员,那么static就没意义了

静态全局变量和函数

修饰全局变量时,表明一个全局变量只对定义在同一文件中的函数可见。

修饰函数时,表明该函数只能在同一文件中调用。

static const

常量+只在当前模块中可见

C++中const是实例成员,不能在类定义处初始化,不同对象可以不同(构造初始化列表),不能由类名直接访问

C#中的const是隐式static的,可以由类名直接访问。C++const更接近于只读,所以两者的const是不同的

C#

静态类

  1. 静态类的本质,是一个抽象的密封类,所以不能被继承,也不能被实例化。
  2. 静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 new 关键字创建静态类类型的变量。也不能有非静态成员(即实例成员)
  3. 不支持继承,所以静态类不能包含protected成员。但是可以实现接口。interface不能是静态的
  4. 静态类通常是收集一些常用的方法,与面向对象无关了

执行顺序(经过测试)

静态初始化器-静态构造函数-初始化器-构造函数

静态构造函数

  1. 这个类的成员,第一次被访问之前,会执行静态构造函数。如类被实例化或者静态成员被调用的时候进行调用,并且是由.net框架来调用静态构造函数来初始化静态成员变量
  2. 静态构造函数只被执行一次
  3. 静态构造函数不可被访问限制符修饰, 因为静态构造函数不是我们程序员调用的,是由.net 框架在合适的时机调用的。
  4. 静态构造函数没有参数,因为框架不可能知道我们需要在函数中添加什么参数,所以规定不能使用参数。
  5. 一个类中只能有一个静态构造函数。
  6. 无参数的静态构造函数和无参数的构造函数是可以并存的。因为他们一个属于类级别,一个属于实例级别,并不冲突。
  7. 如果我们在类中定义了静态变量,但是又没有定义静态构造函数,那么框架也会自动生成一个静态构造函数以初始化类。

静态与初始化器

  1. 初始化器:即声明字段后直接用=赋值
  2. 系统默认的初始化会将会在所有代码执行前把一切都设置成0或者null,所以这时无需用初始化器
  3. 静态构造函数在标准构造函数之前运行

静态成员

  1. 非静态类可以包含静态的方法、字段、属性或事件;
  2. 无论对一个类创建多少个实例,它的静态成员都只有一个副本;
  3. 静态方法和属性不能访问其包含类型中的非静态字段和事件,并且不能访问任何对象的实例变量;
  4. 可以在静态方法中定义变量并使用,和普通方法一样
  5. 静态方法只能被重载,而不能被重写,因为静态方法不属于类的实例成员
  6. 常量本质是静态的:虽然字段不能声明为 static const,但 const 字段的行为在本质上是静态的。这样的字段属于类,不属于类的实例。因此,可以同对待静态字段一样使用 ClassName.MemberName 表示法来访问 const 字段;
  7. 可以用 static readonly(只读不同于常量)
  8. this/base 关键字在静态方法中不能使用,因为有可能对象还不存在。
  9. 类加载的时候,所有的静态成员就会被创建在“静态存储区”里面,一旦创建直到程序退出,才会被回收。

注:Person p;  //这样实际上就已经被加载了。

其他类可以直接 类名.静态变量名 来访问,就像静态类一样

静态局部变量

C++

函数中的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量保留上一次函数调用结束时的值。

为静态局部变量赋初值是在编译时进行值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。

C#

c#不支持方法内的静态变量,原因有二。

1. 一般来说方法内的静态变量可以用该方法所属类的静态成员变量代替

2. 方法中的静态变量会在多线程的应用里造成不比要的麻烦。

其他

C#:不要把 static 成员变量的初始化动作安排在类的构造函数中,因为构造函数可能一再被调用,而变量的初值却只应该设定一次。

C++:也不要把初始化动作安排在头文件中,因为它可能会被包含许多地方,因此也就可能被执行许多次。你应该在实现文件中且类别以外的任何位置设定其初值。例如在 main 之中,或全域函数中,或任何函数之外

原文地址:https://www.cnblogs.com/sols/p/8761590.html

时间: 2024-11-11 10:09:08

【总结】C++与C#中的static静态修饰符的相关文章

有关static静态修饰符的学习心得

初学java,面对着这个static修饰符,愣是琢磨了两天时间,还在今天琢磨透了,现在将悟到的东西记录下来: 1.static修饰符表示静态修饰符,其所修饰的内容(变量.方法.代码块暂时学到这三种)统称为静态内容(静态变量.静态方法.静态代码块) 2.静态内容是与类相关的内容.解释:静态变量在类加载时就会被分配内存空间,而且只会被分配一次,也就是说静态变量对类内部是共享的,大家都可以去调用访问它,只要在一个调用里改变了它的值,那么所有调用内部的值全部都会被改变.静态方法也是在类加载时就分配了入口

Static.final修饰符、super关键字及常量与变量

一.Static static 静态修饰符,用来修饰类的属性或方法 如果类的某个属性,不管创建多少个对象,属性的存储空间只有唯一的一个,那么这个属性就应该用static修饰,称为静态属性. static属性可以使用对象调用,也可以直接用类名调用,静态属性是类的所有对象共享的,即不管创建了多少个对象,静态属性在内存中只有一个. static块和static的属性以及方法的性质是相同的,用static修饰的代码块表示静态代码块,当Java虚拟机加载类时,就会执行该代码块. 静态块只有在类加载的时候被

静态修饰符

静态修饰符(static) Static 静态修饰符      1.修饰成员变量     2.修饰方法 1.用来修饰成员变量:一个成员变量被static修饰叫静态成员变量,如果没有被修饰叫非静成员变量. 访问方式:(1)用对象进行访问:    对象名.变量名 (2)可以通过类名来访问:  类名.变量名 需要注意的点: (1)不要认为所有的变量都用static修饰,只有数据真正需要共享时才需要static修饰 (2)只有静态变量才能用类名访问,非静态变量只能用对象访问 (3)局部变量不允许被sta

静态修饰符static,类中的常量定义修饰符

static可以用来区分成员变量.方法是属于类本身还是属于类实例化后的对象.有static修饰的成员属于类本身,没有static修饰的成员属于类的实例. 静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失static是一个修饰符,用于修饰成员(成员变量和成员函数)静态成员随着类的加载而加载.静态成员优先于对象存在.静态成员被所有对象所共享静态成员多了一个中调用方式,可以被类名直接调用.静态的优缺点优点: 静态成员多了一种调用方式.可以直接被类名调用 格式 :类名.静态成员.也

C#中override和new修饰符的区别

(new)“隐藏”,(override)“覆盖”(重写).不过要弄清楚这两个有什么区别确实也很难,因为子类在使用父类方法时根本看不出区别,子类不管父类是new了还是override了,用的都是父类方法.区别就在于,一个子类对象中,用父类类型指针去访问子类成员时有区别. 如果是new的,那么父类的这个函数地址仍然保留着,同时又提供了一个新的子类的该函数入口地址.也就是说子类对象中同时保存了两个入口地址,父类的该函数地址被“隐藏”,但是它还可以用父类的类型指针访问得到:用子类类型指针访问该函数,则进

《挑战30天C++入门极限》入门教程:C++中的const限定修饰符

    入门教程:C++中的const限定修饰符 const修饰符可以把对象转变成常数对象,什么意思呢? 意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用! 使用方法是: const int a=1;//这里定义了一个int类型的const常数变量a; 但就于指针来说const仍然是起作用的,以下有两点要十分注意,因为下面的两个问题很容易混淆! 我们来看一个如下的例子: #include <iostream> using namespace std;

[转] C# 中的static静态变量

logitechyan原文关于C#中static静态变量 C#静态变量使用static 修饰符进行声明,在类被实例化时创建,通过类进行访问不带有 static 修饰符声明的变量称做非静态变量,在对象被实例化时创建,通过对象进行访问一个类的所有实例的同一C#静态变量都是同一个值,同一个类的不同实例的同一非 静态变量可以是不同的值.静态函数的实现里不能使用非静态成员,如非静态变量.非静态函数等. 使用 static 修饰符声明属于类型本身而不是属于特定对象的静态成员static修饰符可用于类.字段.

java静态修饰符static的使用

class Person { private String name; private int age; /* * 假设每个Person对象的国籍都一样, * 那么每次调用都要赋值就会不合理. * 使用static修饰,国籍优先确立, * 每个对象建立时,都默认赋予了该国籍. */ static String country = "China"; Person (String name,int age) { this.name = name; this.age = age; } pub

java中四种访问修饰符

Java中的四种访问修饰符:public.protected.default(无修饰符,默认).private. 四种修饰符可修饰的成分(类.方法.成员变量)   public protected default private 类 √ × √ ×(内部类可以用private修饰) 方法 √ √ √ √ 成员变量 √ √ √ √ 四种修饰符的访问权限 public:对所有类可见 protected:对同一包中的类可见.对同一包及不同包中的子类可见 default:对同一包中的类可见.对同一包中的