《随笔五》——C#中的 —— “ 静态成员的生存期 、静态成员函数、成员常量”

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34536551/article/details/83957585

目录

静态成员的生命期

静态成员函数

成员常量

常量与静态量


先看一个静态字段的示例:

namespace Ch05Ex03
{
    class Persion
    {
        int Mem1;
        static int Mem2; //私有静态成员
        static Persion()
        {
            Mem2 = 900;
            //Mem1 = 200; //不可以在静态构造函数中初始化 非静态字段
            WriteLine("静态构造函数被调用!\n");
        }
        public Persion(int aa,int bb)
        {
            Mem1 = aa;
            Mem2 = bb; //利用构造函数设置私有静态成员
            WriteLine("\n实例构造函数被调用!\n");
        }
        public void SetVars(int v1,int v2)
        {
            Mem1 = v1;
            Mem2 = v2;
        }
        public void Display(string str)
        {
            WriteLine($"{str}: Mem1的值:{Mem1}, Mem2的值:{Mem2}");
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Persion d1 = new Persion(2, 8);  //利用公有构造函数设置静态字段和普通字段的值
            d1.Display("d1");
            Persion d2 = new Persion(5, 77);
            d2.Display("d2");

            WriteLine();
            d1.SetVars(7, 22); //利用公有成员函数设置静态字段和普通字段的值
            d1.Display("d1");
            
            d2.SetVars(99, 100);
            d2.Display("d2");
            d1.Display("d1"); //这里再次输出d1的值,输出就是 7,100,因为它被d2 改变了

            // 注意下面的代码:
            Persion d3 = new Persion(141, 55), d4 = new Persion(454, 666);

            /*该代码输出:
             * d3: Mem1的值:141, Mem2的值:666
              d4: Mem1的值:454, Mem2的值:666

              为什么d3的值是141和666, 而不是141,55 呢?
              首先执行该代码的时候我们调用实例构造函数执行成员初始化,我们首先初始化实例d3的成员,然后设置
              d4的成员 ,设置d3的时候我们初始化Mem1为141,Mem2 = 55, 设置d4的值时初始化Mem1为454. Mem2 = 666.
              因为静态字段被类的所有实例所共享, 所有实例都访问同一内存位置。因此d4把静态字段Mem2的值改变了,
             因此 d3的 Mem2 的值也改变了。*/
            d3.Display("d3");
            d4.Display("d4");

            ReadKey();
        }
    }
}

输出结果为:

静态构造函数被调用!

实例构造函数被调用!

d1: Mem1的值:2, Mem2的值:8

实例构造函数被调用!

d2: Mem1的值:5, Mem2的值:77

d1: Mem1的值:7, Mem2的值:22
d2: Mem1的值:99, Mem2的值:100
d1: Mem1的值:7, Mem2的值:100


实例构造函数被调用!

实例构造函数被调用!

d3: Mem1的值:141, Mem2的值:666
d4: Mem1的值:454, Mem2的值:666

那为什么没有输出静态构造函数中设置的值呢,道理都是一样的,程序首先调用的就是静态构造函数,调用之后  Mem2 = 900; Mem1=0; 记住: 不管这个类有多少个类实例, 静态构造函数只调用一次。

然后就调用实例构造函数,实例构造函数设置的值直接覆盖了静态构造函数中的值,所以输不出静态构造函数设置的值。


静态成员的生命期


●  只有在实例创建之后才产生实例成员,在实例销毁后实例成员就不存在了。

● 但静态成员,即使类没有实例,也存在静态成员,并且可以访问。(在C++中不可以这样)

namespace Ch05Ex03
{
    class D
    {
        static public int Mem2; //但是如果设置为私有的静态成员,就不可以在类外通过类直接访问
    }
    class Program
    {
        static void Main(string[] args)
        {
            D.Mem2 = 5; //通过类名直接为公有静态数据成员赋值, 但是如果该成员是私有,就不可以这样赋值
            WriteLine(D.Mem2);
            ReadKey();
        }
    }
}

输出结果为:

5

注意: 静态成员即使没有类的实例也存在。如果该静态字段有初始化语句,那么会在使用该类的任何静态成员之前初始化该字段, 但没必要在程序执行的开始就初始化。


静态成员函数


● 如同静态字段,静态成员函数独立于任何类实例。 即使没有类的实例,仍然可以调用静态方法。(C++中不可以这样)

● 注意:类成员函数(无论是static成员函数或非static成员函数)都可以直接访问static数据成员,static 成员函数仅能访问static 数据成员,不能访问非static的数据成员,也不能访问非static 的成员函数。
 

namespace Ch05Ex03
{
    class D
    {
 
        static public int Mem2;
        public int aa = 10; //在类定义中初始化一个非静态的公有成员
        static public void PrintVal() //静态成员函数访问静态成员数据
        {
            WriteLine(Mem2);
            //WriteLine(aa); 静态成员不可以访问非静态数据成员
        }
        public void getVal()
        {
            WriteLine(aa);  // 输出aa的值
             WriteLine(Mem2); //非静态函数可以访问静态的数据成员
        }
    }
  
    class Program
    {
        static void Main(string[] args)
        {
            D.Mem2 = 5;
            D.PrintVal();
 
            D dd = new D(); // 创建该类的对象
            dd.getVal(); 
            ReadKey();
        }
    }
}
 
输出结果为:
5
10
5

在C++中可以声明常量为静态的常量成员数据, 而在C#中却不可以。

与C++不同,在C#中没有全局常量。 每个常量都必须声明在类型内。


成员常量


namespace Ch05Ex03
{
    class D
    {
        //用于初始化常量的值必须是在编译时就可以确定的,通常是一个简单类型的值或者一个表达式
        const int Mem2 = 5;
        const int Mem3 = 2 * Mem2; // 正确, 但是Mem2 必须是一个const字段,否则错误。
    }
    class Program
    {
        static void Main(string[] args)
        {         
            ReadKey();
        }
    }
}

常量与静态量


●  注意: 常量成员即使没有类的实例也可以使用。 与真正的静态量不同, 常量没有自己的存储位置, 而是在编译时被编译器替换。 跟C++中的 #define 类似。

看一个C++的程序:

class D
{
 
public:
	const double PI = 3.14;
	D(decltype(PI) aa):PI(aa)
	{
		
	}
};
 
int main()
{
	D dd(22.3);
	cout << dd.PI << endl;
	system("pause");
	return 0;
}

看一个C#程序:

namespace Ch05Ex03
{
    class D
    {
        public const double PI = 3.14;
       
    }
  
    class Program
    {
        static void Main(string[] args)
        {
            WriteLine(D.PI);   //利用类实例访问公有常量数据成员
            ReadKey();
        }
    }
}

在C#中常量成字段现得像一个静态量 但不能将常量字段声明成 static:

static const double PI = 3.14; //错误

但是在C++中可以。

猜你喜欢

转载自blog.csdn.net/qq_34536551/article/details/83957585