본문 바로가기
스터디/C++

[ C++ ] static 멤버변수( 클래스 변수 )와 static 멤버함수, mutable

by 알 수 없는 사용자 2019. 9. 26.

C++에서의 static은 C언어에서의 static이 그대로 통용된다. 

 

C에서의 static 특징

- 전역 변수에 선언된 static은 선언된 파일 내에서만 참조를 허용한다.

- 함수 내에 선언된 static은 한 번만 초기화되고, 함수를 빠져나가도 소멸되지 않는다.

 

먼저 A 클래스와 B 클래스 두개가 있다고 치자.

A 클래스는 Plus_1 함수 호출할 때마다 숫자를 1씩 더하고

B 클래스는 Plus_2 함수 호출할 때마다 숫자를 2씩 더한다.

 

그럼 이를 전역변수를 사용한 코드를 보겠다.

 

그럼 여기서 확인할 수 있는 점은

a_num은 클래스 A를 위한 전역 변수이다.

b_num은 클래스 B를 위한 전역 변수이다.

 

즉, a_num은 A형 객체들이 공유하는 변수이고 b_num은 B형 객체들이 공유하는 변수이다.

하지만 둘은 전역 변수이기에 동일한 객체들끼리 공유한다는 제한을 둘 수 없다.

 

그래서 나온 변수가 static 멤버 변수(클래스 변수)이다.

일반적인 멤버 변수와 달리 클래스당 하나씩 생성된다. 

 

그럼 이전 예제를 static 멤버 변수를 활용하여 바꿔보겠다.

static 멤버 변수는 항상 외부에서 초기화한다.

static 멤버 변수는 이외에도 다르게 접근이 가능하다.

 

다음 예제를 보자.

private 였던 static 멤버 변수를 pubblic으로 하여 전역에 접근 가능하게 했다.

일단 그것에 초점을 두지 말고 출력 결과를 보자.

 

A 객체나 B 객체 둘 다 하나도 생성하지 않은 상태임에도 클래스의 이름을 이용하여 static 멤버 변수에 접근하고 있다.

즉, static 멤버 변수는 객채 내에 존재하지 않는 점도 알 수 있다.

 

하지만 클래스 내에서 초기화를 할 수 있는 방법이 있다. 

바로 const를 사용하여 선언과 동시에 초기화를 해버리면 된다.

 

 

static 멤버 함수도 static 멤버 변수와 특성이 동일하다.

- 선언된 클래스의 모든 객체가 공유한다.

- public으로 선언되면, 클래스의 이름으로 호출 가능하다.

- 객체의 멤버로 존재하지 않는다.

 

객체의 멤버로 존재하지 않는 점을 주목하자. 

class A
{
private:
	int num1;
    static int num2;
public:
	A(int n): num1(n)
    { }
    
    static void Adder(int n)
    {
    	num1 += n; // 컴파일 에러
        num2 += n;
    }
};
int A::num2 = 0;

 

 

static 함수도 객체의 멤버로 존재하지 않기에 객체 생성 이전에도 호출이 가능하기에 멤버 변수에 접근이 불가능하다.

접근을 한다 해도 어떤 객체의 멤버 변수에 접근해야 할지 모르기 때문이다.

 

즉, "static 멤버 함수 내에서는 static 멤버 변수와 static 멤버 함수만 호출이 가능하다."

 

 

 

mustable는 const 함수 내에서의 값 변경을 예외적으로 허용한다는 키워드이다.

const 함수는 객체 내의 데이터 변경을 하지 않겠다는 의미지만, mustable로 선언된 num2의 값을 변경했다.

그래서 num2는 const의 선언을 의미 없게 만들어버렸다.

 

이렇듯, mutable은 예외적인 경우에 한해서 사용하는 키워드이고 사용 빈도수도 적기 때문에 문법적으로만 기억을 하자.