PHP静态成员变量和非静态成员变量的详细说明
数据成员可以分为静态变量和非静态变量。
静态成员:静态类中的成员添加了静态修饰符,即静态成员。这个静态成员可以通过使用类名的静态成员名直接访问。因为静态成员存在于内存中,所以需要实例化非静态成员来分配内存,所以静态成员不能访问非静态成员。因为静态成员存在于内存中,所以非静态成员可以直接访问类中的静态成员。
非静态成员:所有没有静态的成员都是非静态成员。在类被实例化之后,可以通过实例化的类名来访问它们.非静态成员的生存期取决于类的生存期.静态成员没有生存期的概念,因为静态成员总是驻留在内容中.
一个类也可以包含静态成员和非静态成员,它还包括静态构造函数和非静态构造函数。从两个方面进行总结。第一个方面主要是相对于面向过程的,即这方面不涉及类;第二个方面是相对于面向对象的,它主要解释了静态在类中的作用。
1.面向过程设计中的静态关键字
1.静态全局变量
定义:在全局变量前,添加关键字static,变量定义为静态全局变量。
特点:
A.变量在全局数据区分配内存。
b初始化:如果不显式初始化,将隐式初始化为0(自动变量是随机的,除非显式初始化)。
C.访问变量只在源文档中可见,严格来说,它们应该从文档的开头到结尾进行定义。
示例(摘自钱能编辑的c程序设计教程-p103)://file 1 . CPP//example 1 # include void fn();静态整数n;//定义静态全局变量void main(){ n=20;cout fn();} void fn(){ n;Cout }D,文件作用域下声明的const的常量默认为静态存储类型。
静态变量都在全局数据区分配内存,包括后面提到的静态局部变量。对于一个完整的程序,内存中的分布如下:
new生成的通用程序动态数据存储在堆区,函数内部的自动变量存储在栈区。自动变量通常随着函数的退出释放空间,静态数据(甚至函数内部的静态局部变量)存储在全局数据区。由于函数的退出,全局数据区中的数据不会释放空间。细心的读者可能会发现,示例1中的代码将
静态整数n;//定义静态全局变量
更改为:
int n;//定义全局变量
程序仍然正常运行。的确,定义全局变量可以实现文件中变量的共享,但是定义静态全局变量有以下好处:
静态全局变量不能被其他文件使用;同名的变量可以在其他文件中定义(好像和extern不一样),不会有冲突;您可以将上面的示例代码更改如下:
//示例2//file 1 #包含void fn();静态整数n;//定义静态全局变量(只能在本文档中使用)。void main(){ n=20;cout extern int n;(此变量可以在其他文件中引用)void fn(){ n;Cout编译运行例2,你会发现上面的代码可以单独编译,但是链接有错误。尽量把静态int n;//定义静态全局变量
代替
int n;//定义全局变量
再次编译运行的程序,仔细理解全局变量和静态全局变量的区别。
2.静态局部变量
定义:静态局部变量是在局部变量前添加static关键字时定义的。
让我们以静态局部变量为例,如下所示:
//示例3 #包含void fn();void main(){ fn();fn();fn();} void fn(){ static n=10;Cout通常在函数体中定义一个变量,并在程序运行到语句时为局部变量分配堆栈内存。然而,当程序退出函数体时,系统将回收堆栈内存,局部变量将相应地失败。
但有时我们需要在调用之间保存变量值。总的思路是定义一个全局变量。但这样一来,变量就不再属于函数本身,不再只受函数控制,给程序维护带来不便。
静态局部变量可以解决这个问题。静态局部变量保存在全局数据区,而不是堆栈中,每次的值都保留到下一次调用,直到下次分配新值。
特点:
A.变量在全局数据区分配内存。
b初始化:如果没有显式初始化,会隐式初始化为0,后续的函数调用不会初始化。
c,它总是驻留在全局数据区,直到程序运行。但是,它的作用域是局部作用域,当定义它的函数或语句块结束时,它的作用域就结束了。
3.静态函数(注意与类的静态成员函数的区别)
定义:通过在函数的返回类型前添加static关键字,将函数定义为静态函数。
特点:
a、静态函数不同于普通函数,它只能在声明它的文件中看到,不能被其他文件使用。
静态函数的示例:
//示例4 #包含静态void fn();//声明静态函数void main(){ fn();}void fn()//定义了一个静态函数{ int n=10cout定义静态函数的好处:
静态函数不能被其他文件使用;同名函数可以在其他文件中定义,不会产生冲突。二、面向对象的静态关键字(类中的静态关键字)
1.静态数据成员
在类中的数据成员声明之前添加关键字static,数据成员就是类中的静态数据成员。让我们举一个静态数据成员的例子。
//示例5 #包含类Myclass { public : Myclass(int a,int b,int c);void GetSum();private: int a,b,c;静态int Sum//声明静态数据成员};int myclass :3360 sum=0;//定义并初始化静态数据成员MyClass : MyClass (int a,int b,int c){ this-a=a;this-b=b;this-c=c;总和=a b c;} void my class : getsum(){ cout ' sum='可以看出,静态数据成员具有以下特征:
对于非静态数据成员,每个类对象都有自己的副本。而静态数据成员被视为类成员。不管定义了多少个这个类的对象,程序中只有一个静态数据成员的副本,所有这种类型的对象都可以共享和访问。也就是说,静态数据成员对类的所有对象都是公共的。对于此类的多个对象,静态数据成员只为所有要共享的对象分配一次内存。因此,静态数据成员的值对于每个对象都是相同的,并且其值可以更新;静态数据成员存储在全局数据区。静态数据成员在定义时需要分配空间,因此不能在类声明中定义。在示例5中,语句int Myclass : sum=0;是定义静态数据成员;静态数据成员像普通数据成员一样遵循公共的、受保护的、私有的私有访问规则;因为静态数据成员在全局数据区分配内存,属于这个类的所有对象都是共享的,所以它不属于特定的类对象,在没有生成类对象时,也就是没有生成类的实例时,它的作用域是可见的,我们可以对它进行操作;静态数据成员初始化不同于一般的数据成员初始化。静态数据成员的初始化格式为: <数据类型> <类名> :3360 <静态数据成员名>=<值>。类的静态数据成员有两种访问形式: <类名>。<静态数据成员名称>或<类类型名称> :3360 <静态数据成员名称>。如果静态数据成员的访问权限允许(即静态数据成员主要用于所有对象具有相同属性时。例如,对于存款类,每个实例的利息是相同的。因此,利息应设置为存款类的静态数据成员。这有两个好处。首先,无论定义多少存款类对象,利息数据成员共享全局数据区分配的内存,节省了存储空间。第二,一旦利息需要变动,只要变动一次,所有存款类对象的利息都会变动;与全局变量相比,使用静态数据成员有两个优点:静态数据成员不进入程序的全局命名空间,因此不存在与程序中其他全局名称冲突的可能性;
可以实现信息隐藏。静态数据成员可以是私有成员,而全局变量不能。
2.静态成员函数
像静态数据成员一样,我们也可以创建一个静态成员函数,它服务于所有的类,而不是某个类的特定对象。像静态数据成员一样,静态成员函数是类的内部实现,是类定义的一部分。普通成员函数通常隐含一个指向类对象本身的this指针,因为普通成员函数总是属于一个类的特定对象。通常,这是默认设置。例如,函数fn()实际上就是这个-fn()。但是,与普通函数相比,静态成员函数没有这个指针,因为它们不与任何对象相关联。从这个意义上说,它不能访问属于类对象的非静态数据成员,也不能访问非静态成员函数。它只能调用其他静态成员函数。让我们举一个静态成员函数的例子。
//示例6 #包含类Myclass { public : Myclass(int a,int b,int c);静态void GetSum();/声明静态成员函数private: int a,b,c;静态int Sum//声明静态数据成员};int myclass :3360 sum=0;//定义并初始化静态数据成员MyClass : MyClass (int a,int b,int c){ this-a=a;this-b=b;this-c=c;总和=a b c;//非静态成员函数可以访问静态数据成员} voidymclass :3360 GetSum()//静态成员函数的实现{//Cout类的静态成员不同于一般的类成员。静态成员与对象的实例无关,只与类本身有关。它们用于实现类要封装的函数和数据,但不包括特定对象的函数和数据。静态成员包括静态方法和静态属性。
静态属性包含要封装在类中的数据,并且可以由类的所有实例共享。事实上,类的静态属性与函数的全局变量非常相似,只是它属于一个固定的类并限制访问。
静态方法实现了类需要封装的功能,与特定对象无关。静态方法非常类似于全局函数。静态方法可以完全访问类的属性,也可以由对象的实例访问,而不管访问什么限定符。
不包含任何非静态成员的类可以称为静态类,静态类也可以理解为全局变量和函数的命名空间!
普通方法使用-to调用。PHP会创建一个这个变量,而静态方法不属于任何对象。在某些情况下,我们甚至想在没有有效对象的时候调用它,所以我们应该使用静态方法。PHP不会在静态方法中创建这个变量,即使你从一个对象中调用它们。
您可以编写一个方法,通过判断它是否成立来显示这是静态调用还是非静态调用。当然,如果使用static关键字,无论如何调用,这个方法总是静态的。
您的类也可以定义常量属性,而不是使用公共静态,您只需要使用const关键字。常量属性总是静态的。它们是类的属性,而不是实例化类的对象的属性。
PHP静态方法和非静态方法的效率
1.静态成员的访问效率不一定比非静态成员高。
2.只需要调用一个类的方法的返回值,使用静态的方法更合理,否则会因为new而产生额外的开销。
上面提到的是边肖介绍的PHP静态成员变量和非静态成员变量,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!
版权声明:PHP静态成员变量和非静态成员变量的详细说明是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。