'정적변수'에 해당되는 글 2건

  1. 2015.06.12 C++ 클래스의 정적(static) 멤버
  2. 2015.05.18 C++의 정적 변수(static variable)

 클래스의 모든 멤버 변수와 멤버 함수는 정적(static) 멤버로 지정될 수 있다. 정적 멤버 변수는 인스턴스가 생성될 때마다 독립적으로 생기는 멤버 변수와 달리 해당 클래스에 하나만 생성되고 모든 인스턴스에서 공동으로 접근할 수 있는 변수이다. 마찬가지로 정적 멤버 함수도 클래스당 하나만 생기며 모든 인스턴스에서 공동으로 호출할 수 있다.


 멤버를 정적 멤버로 선언하려면 선언문 앞에 static 이라는 지정자를 붙이면 된다. 모든 멤버들이 static으로 선언될 수 있으며 정적 멤버들도 접근 지정자 (public, protected, private)을 붙일 수 있다.

1 정적 멤버 변수

 이전 포스트의 LED 클래스의 예를 가지고 정적 멤버 변수를 추가시켜 보면 다음과 같다.

class Led {
   public:
       Led();
       void turnOn();
       void turnOff();
       static int iCount; // 정적 멤버 변수
   private:
       byte _pin;
};

이 예제에서 iCount는 정적 멤버 변수로 선언되었다. 정적 멤버 변수를 초기화하기 위해서는 클래스 내부에서는 불가능하다. 다음과 같이 초기화 하려고 하면 에러를 발생한다.


class Led {
   public:
       Led();
       void turnOn();
       void turnOff();
       static int iCount = 0; // 오류 발생
   private:
       byte _pin;
};

 

따라서 클래스 외부에서 전역 변수처럼 초기화시켜야 한다.

int Led::iCount = 0;

정적 변수를 접근하는 방법은 두 가지가 있는데 먼저 클래스 이름으로 접근하는 것이다. 이때 범위 지정 연산자인 ::을 이용한다.


Led::iCount ++; // iCount값을 하나 증가시킨다.

 

또는 인스턴스를 이용해서도 접근할 수 있다.

Led led1(12), led2(11);
led1.iCount = 10;
led2.iCount = 30;

비록 인스턴스 멤버 변수를 접근하는 문법과 똑같지만 서로 다른 인스턴스를 통해서 정적 변수를 참조했다고 할지라도 결국 같은 하나의 정적 변수 iCount를 접근하는 것이다.

 정적 변수의 첫 번째 활용 목적은 인스턴스들 사이에서 공유할 변수를 만들고자 하는 것이다. 예를 들어서 인스턴스가 몇 개나 생성되었는지를 기록하고자 할 때 앞의 예에서 iCount를 사용하면 될 것이다. 이 경우 생성자 내에서 iCount 값을 증가시키면 새로운 인스턴스가 생성될 때마다 이 변수값이 증가되므로 이것으로 개수를 알 수 있다.

int Led::iCount = 0; // 전역에서 정적 멤버 변수 초기화
Led::Led(int pin) { //생성자
   _pin = pin;
   pinMode(_pin, OUTPUT);
   iCount++; // 인스턴스 생성 시 하나 증가
}
Led::~Led(int pin) { //소멸자
   iCount--; // 인스턴스 소멸 시 하나 감소
}

또한 전역 변수를 쓰는 대신 관련된 클래스 내부에 정적 멤버 변수를 집어넣어서 C언어의 전역 변수처럼 사용할 수도 있다.

2 정적 멤버 함수

 멤버 함수 앞에 static 이라는 키워드를 붙이면 정적 멤버 함수가 된다. 정적 변수와 마찬가지로 정적 멤버 함수는 인스턴스에 속하는 멤버 함수가 아니라 클래스에 속하는 하나의 함수이다. 정적 함수 내부에서는 오직 정적 변수만을 사용할 수 있으며 함수도 정적 함수만을 호출할 수 있다. 반대로 일반 멤버 함수에서는 정적 멤버를 접근하는데 전혀 제약이 없다. 다음 예를 보자.

class Util {
   public:
       int iA;
       static double dA;

       void getA() {
           iA += (int)dA; // 정적과 비정적 변수를 모두 사용가능
           return iA;
       }

       static void getB() { // 정적 함수
           return dA; //정적 변수만 사용 가능
       }
};


비정적 함수 getA() 내부에서는 변수 iA와 정적 변수 dA를 사용하는데 아무런 제약이 없으나 정적함수 getB() 에서는 정적 변수 dA만 사용할 수 있다. 마찬가지로 정적 함수 내에서는 정적인 함수만 호출할 수 있으며 일반적인 멤버 함수는 호출할 수 없다.



Posted by 살레시오
,

 정적(static) 변수는 전역 변수와 지역 변수의 중간쯤 되는 특성을 가진다. 정적변수도 전역정적 변수와 지역 정적 변수로 나뉘지만 여기에서는 지역 정적 변수에 대해서만 설명하도록 하겠다.


 지역 정적 변수는 함수의 수행이 끝나더라도 그 값을 유지시켜야만 할 때 사용되는 것이다. 즉, 이 변수는 함수의 수행이 끝나더라도 소멸되지 않으며 그 값을 유지하고 있으며 프로그램의 수행이 끝날 때까지 그 값을 유지하는 변수이다.


 정적 변수는 static이라는 키워드를 데이터형 앞에 붙여주면 되는데 다음과 같이 정의한다.


함수() {
   static 데이터형 변수명1, 변수명2, ...;
}


이렇게 정의된 변수들은 프로그램의 수행이 시작될 때 생성되며 함수의 수행이 끝나더라도 그 값이 유지되며 다음에 호출되었을 때 그 유지된 값을 이용할 수 있다. 프로그램이 실행될 때 생성되고 끝날 때 까지 보존이 된다는 점에서 전역 변수와 라이프 싸이클이 같지만 선언된 함수 내부에서만 사용할 수 있다는 점이 다르다.


다음의 예에서 간단한 사용법을 보였다.


#include <stdio.h>
void countUp(int);

int main(void) {
   int iIn;
   do {
       printf("Input an interger number : ");
       scanf("%d", &iIn);
       countUp(iIn);
   }
   while (0<=iIn && iIn<=10);
}

void countUp(int iR) {
   static int iCount = 0; //❶
   printf("%d번째 수는 %d.\n", ++iCount, iR);
}

실행결과:

Input an interger number : 8
1번째 수는 8.
Input an interger number : 4
2번째 수는 4.
Input an interger number : 10
3번째 수는 10.
Input an interger number : 0
4번째 수는 0.
Input an interger number : -1
5번째 수는 -1.


 이 예제는 사용자가 입력한 숫자가 0이상 10이하라면 다시 입력받고 현재까지 몇 개가 입력되었는가를 세는 간단한 프로그램이다. 이 예제의 countUp()함수 안의 ❶번 줄에서 iCount 변수가 정적 변수로 선언되었다. 따라서 이 함수가 종료되더라도 그 값은 계속 유지하며 이 사실은 실행 결과에서 확인할 수 있다.


 내부 정적 변수도 내부 변수이므로 그것이 위치한 함수 내부에서만 접근할 수 있다는 사실은 유의하자.


C++ 강좌 전체 목록 >>>


c{c++},n{c0028}


Posted by 살레시오
,