정적 멤버변수(Static Class Member Variables)
정적 멤버변수의 필요성
생성된 모든 인스턴스들이 공유하는 공통적인 정보가 필요할 때에 사용되는 것이 정적 멤버변수입니다. 정적 멤버변수는 다른 일반 멤버변수와 달리 각각의 인스턴스에 기억장소가 할당되는 것이 아니라, 단 한 개의 기억장소만이 할당되고 모든 인스턴스에 의하여 공유되거나 인스턴스없이 바로 참조할 수 있습니다.
클래스 스코프
정적 멤버변수는 객체 내의 멤버 변수로서 확보 되는것이 아니라, 별도의 영역(클래스 영역)에 확보 되어지는 멤버변수입니다. '클래스와 인스턴스' 글에서 '클래스와 인스턴스 개념을 이용한 객체의 모델링'을 설명하면서 아래와 같은 그림을 보신 적이 있을 것입니다.
이 그림을 가지고 정적 멤버변수를 모델링하게 되면 아래와 같을 것입니다.
객체를 생성할 때마다 정적 멤버변수인 '$차량대수'를 한 대씩 증가시키는 코드에서 '$둘리', '$밍키', '$후키' 객체를 생성하게 되면 정적 멤버변수 '$차량대수'는 3이 저장되어 있을 것입니다. 이와 같이 모든 객체가 공유할 필요가 있는 멤버변수를 정적 멤버변수로 지정하게 되면 어떠한 객체에서 접근하더라도 동일한 멤버변수에 접근할 수 있습니다. 즉, '$둘리->차량대수', '$밍키->차량대수', '$후키->차량대수'는 모두 동일한 멤버변수를 가르키고 있습니다.
Zend 엔진 1.0에서의 정적 멤버변수
Zend 엔진 1.0에서 객체 인스턴스 대신에 클래스명을 통해 클래스 메소드(class method), 즉 정적 멤버함수를 호출할 수 있었으나 객체 인스턴스가 아닌 클래스명을 통하여 클래스 스코프를 갖는 변수에 접근할 수 있는 방법을 지원하지 않았습니다.
정적 멤버함수가 다루어야 할 가장 기본적인 요소(멤버)는 정적 멤버변수입니다. 정적 멤버변수 역시 정적 멤버함수와 마찬가지로 객체와 관계없이 클래스 스코프(사용범위)를 가지고 있기 때문에 정적 멤버함수에서 다룰 수 있는 유일한 멤버변수입니다.
그러나 Zend 엔진 1.0에서 정적 멤버함수만 제공하고 정적 멤버변수를 지원하지 않았기 때문에 정적 멤버함수의 기능을 온전히 이용하기에는 한계가 있었습니다. 예를 들면 각종 문자열 처리 메소드를 모아놓은 라이브러리와 같이 멤버변수가 필요없는 경우에 한하여 정적 멤버함수 기능을 이용할 수 있었지요.
정적 멤버변수의 정의
클래스를 정의할 때 'var' 키워드로 정의되는 멤버변수는 클래스가 인스턴스화할 때마다 새로 만들어지는 인스턴스 변수입니다. 따라서 한 인스턴스 변수에 접근하려면 먼저 그 클래스의 인스턴스를 'new'라는 키워드로 생성해서 접근해야 합니다.
만약 모든 클래스간에 공유하여야 할 변수가 필요하다면 어떻게 할까요. Zend1 엔진에서는 이를 지원하지 않았었으나 2002년 6월경 릴리즈된 Zend 엔진 2.0 알파2 버전에 의하면 Zend2 엔진에서는 클래스간에 공유할 변수를 정의할 수 있게 되었습니다. 이를 위한 키워드가 'static'이며 다음과 같은 형식으로 정의됩니다.
<형식> static 변수명 = 변수값;
정적 멤버변수를 이용하기
일반 멤버변수는 클래스만 선언한다고 해서 호출할 수 있는 것이 아니라 반드시 객체를 생성한 후에 인스턴스를 통하여 호출되어야 합니다. 반면 정적 멤버변수는 인스턴스가 없어도 호출할 수 있습니다. 정적 멤버변수는 특정 인스턴스를 대상으로 수행되는 것이 아니고 위에서 설명한 클래스 스코프를 갖는 멤버이기 때문에 인스턴스없이도 호출이 가능합니다.
정적 멤버변수는 그 클래스 자체에 전역적(클래스 스코프)이며 다른 클래스나 객체에 서로 사용될 수 있습니다. 그래서 정적 멤버변수는 그 클래스의 인스턴스가 있든 없든 상관없이 어느 곳에서나 사용될 수 있는 것입니다. 이러한 경우에는 정적 멤버변수를 정의하고 있는 클래스의 이름을 범위연산자(scope resolver) "::"와 연결되어 사용되어야 합니다.
<형식> 클래스명::정적멤버변수
[code php;gutter:false]
class Logger {
static $m_Instance = NULL;
function Instance() {
if (Logger::$m_Instance == NULL) {
Logger::$m_Instance = new Logger();
}
return Logger::$m_Instance;
}
function Log() {
…
}
};
$Logger = Logger::Instance();
$Logger->Log(); [/code]
static $m_Instance = NULL;
function Instance() {
if (Logger::$m_Instance == NULL) {
Logger::$m_Instance = new Logger();
}
return Logger::$m_Instance;
}
function Log() {
…
}
};
$Logger = Logger::Instance();
$Logger->Log(); [/code]
따라서 '클래스 스코프'의 예제에서 정적 멤버변수 $차량대수는 앞 항목 '클래스 스코프'의 예와 같이 $둘리->차량대수, $밍키->차량대수, $후키->차량대수와 같이 참조할 수도 있으나 '클래스명::차량대수'와 같이 인스턴스없이 참조할 수도 있습니다. 어떻게 참조하든지 동일한 멤버를 다루게 되는 것이지요. 이와 같이 정적 멤버변수가 클래스 스코프를 갖는다는 의미에서 자바에서는 이 변수를 클래스 변수라고 호칭합니다.
'phpclass > 객체모델' 카테고리의 다른 글
{Zend 엔진 2.0 설계초안}06.소멸자 (0) | 2002.12.21 |
---|---|
{Zend 엔진 2.0 설계초안}05.단일화된 생성자 (0) | 2002.12.21 |
{Zend 엔진 2.0 설계초안}04.private 멤버 변수 (0) | 2002.12.21 |
{Zend 엔진 2.0 설계초안}02.개선된 객체모델 (0) | 2002.12.21 |
{Zend 엔진 2.0 설계초안}01.개요 (0) | 2002.12.21 |