'정적변수'에 해당되는 글 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 살레시오

댓글을 달아 주세요