PHP의 정적 멤버 변수와 비정적 멤버 변수에 대한 자세한 설명

墨辰丷
풀어 주다: 2023-03-27 22:44:01
원래의
1520명이 탐색했습니다.

데이터 멤버는 정적 변수와 비정적 변수 두 가지로 나눌 수 있습니다. 이 글에서는 주로 PHP 정적 멤버 변수와 비정적 멤버 변수를 소개합니다. 필요한 친구들이 참고할 수 있습니다

데이터 멤버는 두 가지로 나눌 수 있습니다. : 정적 변수 및 비정적 변수 .

정적 멤버: 정적 클래스의 멤버는 static 수식어를 추가하면 정적 멤버이므로 클래스 이름 + 정적 멤버 이름을 사용하여 이 정적 멤버에 직접 액세스할 수 있습니다. 메모리에 존재하며 비정적 멤버는 인스턴스화되어야 합니다. 따라서 정적 멤버는 비정적 멤버에 액세스할 수 없습니다. 정적 멤버가 메모리에 존재하기 때문에 비정적 멤버는 클래스의 정적 멤버에 직접 액세스할 수 있습니다.

비정적 멤버:

정적 멤버가 없는 모든 멤버는 클래스가 인스턴스화되면 인스턴스화된 클래스 이름을 통해 액세스할 수 있습니다. 비정적 멤버의 수명은 클래스의 수명에 따라 결정됩니다. 정적 멤버에는 수명 개념이 없습니다. 정적 멤버는 항상 콘텐츠에 상주하기 때문입니다...클래스에는 정적 멤버와 비정적 멤버도 포함될 수 있고, 클래스에도 정적 생성자와 비정적 생성자가 포함됩니다. .

두 가지 측면으로 요약하자면, 첫 번째 측면은 주로 프로세스 지향 측면에 관련됩니다. 즉, 클래스는 이 측면에 관련되지 않습니다. 두 번째 측면은 객체 지향 측면에 관련되며, 이는 주로 역할을 설명합니다. 클래스의 정적.


1. 프로세스 지향 설계의 static 키워드

1. 정적 전역 변수

정의: 전역 변수 앞에 static 키워드를 추가하면 변수가 정적 전역 변수로 정의됩니다.

특징:

 A. 글로벌 데이터 영역에 메모리를 할당하는 변수입니다.

 B. 초기화: 명시적으로 초기화하지 않으면 암시적으로 0으로 초기화됩니다(자동 변수는 명시적으로 초기화하지 않는 한 무작위입니다).

  C. 액세스 변수는 원본 소스 파일에서만 볼 수 있으며 엄밀히 말하면 정의 시점부터 시작하여 이 파일에서 끝나야 합니다.

例(摘于C++程序设计教程---钱能主编P103):         //file1.cpp 
        //Example 1
       #include 
       void fn();
        static int n; //定义静态全局变量
        void main()
        {
    n=20;
    cout<    fn();
        }
        void fn()
        {
    n++;
    cout<        }
로그인 후 복사

 D. 파일 범위에 선언된 Const 상수는 기본적으로 정적 저장소 유형으로 지정됩니다.

정적 변수는 나중에 언급할 정적 지역 변수를 포함하여 전역 데이터 영역에 메모리를 할당합니다. 완전한 프로그램의 경우 메모리에서의 분포는 다음과 같습니다.


일반적으로 프로그램에서 new에 의해 생성된 동적 데이터는 힙 영역에 저장되고, 함수 내부의 자동 변수는 스택 영역에 저장됩니다. . 자동 변수는 일반적으로 함수가 종료될 때 공간을 해제하고 정적 데이터(함수 내부의 정적 지역 변수도 포함)는 전역 데이터 영역에 저장됩니다. 전역 데이터 영역의 데이터는 함수가 종료될 때 공간을 해제하지 않습니다. 주의깊은 독자라면 예제 1의 코드에서

                                                                                    ~

                                            정적 int n; 실제로 전역 변수를 정의하면 변수를 파일에서 공유할 수 있지만 정적 전역 변수를 정의하면 다음과 같은 이점도 있습니다.


정적 전역 변수는 다른 파일에서 사용할 수 없습니다(extern과 다른 것 같습니다)

다른 동일한 이름을 가진 변수는 충돌 없이 파일에 정의될 수 있습니다.

  • 위의 예제 코드를 다음과 같이 변경할 수 있습니다.

  • //Example 2
    //File1
    #include 
    void fn();
    static int n; //定义静态全局变量(只能在本文件中使用)
    void main()
    {
     n=20;
     cout<
    extern int n;(可在别的文件中引用这个变量)
    void fn()
    {
     n++;
     cout<
    로그인 후 복사

  • 예제 2를 컴파일하고 실행하면 위의 코드는 별도로 전달할 수 있습니다. 컴파일은 되지만 링크시 오류가 발생합니다.
static int n; //정적 전역 변수 정의

int n; //전역 변수 정의

로 변경해 보세요. 프로그램을 다시 컴파일하고 실행하면서 전역 변수와 정적 전역 변수의 차이점을 주의 깊게 이해하세요.


2. 정적 지역 변수

정의: 지역 변수 앞에 static 키워드를 추가하면 정적 지역 변수가 정의됩니다.

먼저 다음과 같이 정적 지역 변수의 예를 들어보겠습니다.

//Example 3
#include 
void fn();
void main()
{
 fn();
 fn();
 fn();
}
void fn()
{
 static n=10;
 cout<
로그인 후 복사

일반적으로 변수는 함수 본문에 정의되어 있으며 프로그램이 실행될 때마다 스택 메모리가 지역 변수에 할당됩니다. 이 진술. 그러나 프로그램이 함수 본문을 종료하면 시스템은 스택 메모리를 회수하고 그에 따라 지역 변수는 유효하지 않게 됩니다.

 하지만 때로는 호출 사이에 변수 값을 저장해야 할 때도 있습니다. 일반적인 아이디어는 이를 수행하기 위해 전역 변수를 정의하는 것입니다. 그러나 이렇게 하면 변수는 더 이상 함수 자체에 속하지 않게 되고 더 이상 함수에 의해서만 제어되지 않게 되어 프로그램 유지에 불편을 초래하게 됩니다.

 정적 지역 변수를 사용하면 이 문제를 해결할 수 있습니다. 정적 지역 변수는 스택이 아닌 전역 데이터 영역에 저장됩니다. 각 값은 다음에 새 값이 할당될 때까지 다음 호출까지 유지됩니다.

특징:

 A. 글로벌 데이터 영역에 메모리를 할당하는 변수입니다.

  B. 초기화: 명시적으로 초기화하지 않으면 암시적으로 0으로 초기화되며 이후의 함수 호출은 더 이상 초기화되지 않습니다.

  C、它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或 语句块结束时,其作用域随之结束。

3、静态函数(注意与类的静态成员函数区别)

定义:在函数的返回类型前加上static关键字,函数即被定义成静态函数。

特点:

  A、静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。   

静态函数的例子:

//Example 4
#include 
static void fn();//声明静态函数
void main()
{
 fn();
}
void fn()//定义静态函数
{
 int n=10;
 cout<
로그인 후 복사

定义静态函数的好处:

  • 静态函数不能被其它文件所用;

  • 其它文件中可以定义相同名字的函数,不会发生冲突;

二、面向对象的static关键字(类中的static关键字)

1、静态数据成员

在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。

//Example 5
#include 
class Myclass
{
public:
 Myclass(int a,int b,int c);
 void GetSum();
private:
 int a,b,c;
 static int Sum;//声明静态数据成员
};
int Myclass::Sum=0;//定义并初始化静态数据成员
로그인 후 복사

Myclass::Myclass(int a,int b,int c)
{
 this->a=a;
 this->b=b;
 this->c=c;
 Sum+=a+b+c;
}

void Myclass::GetSum()
{
 cout<<"Sum="<
로그인 후 복사

可以看出,静态数据成员有以下特点:

  • 对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新;

  • 静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。在Example 5中,语句int Myclass::Sum=0;是定义静态数据成员;

  • 静态数据成员和普通数据成员一样遵从public,protected,private访问规则;

  • 因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它;

  • 静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:

  • <数据类型><类名>::<静态数据成员名>=<值>

  • 类的静态数据成员有两种访问形式:

  • <类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>

  • 如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员 ;

  • 静态数据成员主要用在各个对象都有相同的某项属性的时候。比如对于一个存款类,每个实例的利息都是相同的。所以,应该把利息设为存款类的静态数据成员。这有两个好处,第一,不管定义多少个存款类对象,利息数据成员都共享分配在全局数据区的内存,所以节省存储空间。第二,一旦利息需要改变时,只要改变一次,则所有存款类对象的利息全改变过来了;

  • 同全局变量相比,使用静态数据成员有两个优势:

静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;

可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;

2、静态成员函数

  与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。下面举个静态成员函数的例子。

//Example 6
#include 
class Myclass
{
public:
 Myclass(int a,int b,int c);
 static void GetSum();/声明静态成员函数
private:
 int a,b,c;
 static int Sum;//声明静态数据成员
};
int Myclass::Sum=0;//定义并初始化静态数据成员
Myclass::Myclass(int a,int b,int c)
{
 this->a=a;
 this->b=b;
 this->c=c;
 Sum+=a+b+c; //非静态成员函数可以访问静态数据成员
}
void Myclass::GetSum() //静态成员函数的实现
{
// cout<
로그인 후 복사

클래스의 정적 멤버는 일반 클래스 멤버와 다릅니다. 정적 멤버는 개체의 인스턴스와 아무 관련이 없으며 클래스 자체에만 관련이 있습니다. 클래스가 캡슐화하려는 함수와 데이터를 구현하는 데 사용되지만 정적 멤버에는 정적 메서드와 정적 속성이 포함된 특정 개체의 함수와 데이터가 포함되지 않습니다.

정적 속성에는 클래스에 캡슐화할 데이터가 포함되어 있으며 클래스의 모든 인스턴스에서 공유할 수 있습니다. 실제로 고정 클래스에 속하고 액세스 방법을 제한하는 것 외에도 클래스의 정적 속성은 함수의 전역 변수와 매우 유사합니다.

정적 메서드는 클래스에 의해 캡슐화되어야 하며 특정 개체와 관련이 없는 함수를 구현합니다. 정적 메서드는 전역 함수와 매우 유사하며 클래스의 속성에 완전히 액세스하거나 개체의 인스턴스에서 액세스할 수 있습니다. , 액세스 한정자가 무엇인지 여부에 관계없이.

정적이 아닌 멤버를 포함하지 않는 클래스를 정적 ​​클래스라고 부를 수 있습니다. 정적 클래스는 전역 변수 및 함수의 네임스페이스로도 이해될 수 있습니다!

일반적인 메소드는 ->로 호출됩니다. PHP는 이 변수를 생성합니다. 정적 메소드는 어떤 객체에도 속하지 않습니다. 어떤 경우에는 유효한 객체가 없을 때에도 이를 호출해야 하며, 그런 다음 정적 메소드를 사용해야 합니다. . PHP는 객체에서 호출하더라도 정적 메서드 내에서 이 변수를 생성하지 않습니다.

이 설정 여부를 확인하여 정적 호출인지 비정적 호출인지 표시하는 메서드를 작성할 수 있습니다. 물론 static 키워드를 사용하면 이 메서드는 호출 방법에 관계없이 항상 정적입니다.

클래스는 공개 정적을 사용하지 않고 상수 속성을 정의할 수도 있으며 const 키워드를 사용하면 됩니다. 상수 속성은 클래스를 인스턴스화하는 객체의 속성이 아니라 클래스의 속성입니다.

PHP 정적 메서드와 비정적 메서드의 효율성 문제

1. 정적 멤버 액세스 효율성이 반드시 비정적 멤버보다 높을 필요는 없습니다.

2. 클래스 메서드의 반환 값만 있으면 됩니다. 호출되는 경우 정적 메서드를 사용하는 것이 더 효율적입니다. 합리적입니다. 그렇지 않으면 새로 만들기로 인해 추가 오버헤드가 발생합니다.

위 내용은 이 글의 전체 내용입니다. 모든 분들의 공부에 도움이 되었으면 좋겠습니다.


관련 권장 사항:

jsvariablesscope

JS

에서

변수 및 함수 호이스팅 단계에 대한 자세한 설명 PHP 학습: 사전 정의된 변수 세부정보

위 내용은 PHP의 정적 멤버 변수와 비정적 멤버 변수에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿