Minwoo Dev.

[C++] static, 클래스 안에서의 static 본문

C++

[C++] static, 클래스 안에서의 static

itisminu 2024. 6. 28. 23:43
728x90
반응형
SMALL

static

"전역"의 의미를 갖는 static 키워드를 사용하여 선언한 변수는, 프로그램 시작부터 종료까지 존재하게 된다.

#include<iostream>
using namespace std;

void showN(){
    static int n = 0; // n은 사라지지 않고 계속 존재
    n++;
    cout << n << endl;
}

int main(void){
    for (int i = 0; i < 5;i++)
        showN();
}

 

n이 static으로 선언되었기 때문에 1 이 5번 출력되는 것이 아니고 1 2 3 4 5 순으로 출력되게 된다.

 

반대로, 함수 밖의 전역 범위에 있는 경우도 있다.

이런 경우에는 static을 붙이지 않아도 전역 변수로써 작동한다. (정확히는 두 방식은 차이가 있다. 다음 게시글에서 다루겠다.)

#include<iostream>
using namespace std;

static int n = 0;

void showN(){
    n++;
    cout << n << endl;
}

int main(void){
    for (int i = 0; i < 5;i++)
        showN();
}

 

결과는 동일하다.

 

 

C++에서는 이 static 키워드를 클래스에 적용하여 사용한다.

제일 바깥의 전역 변수로 선언하면, 어떤 클래스에서 사용하는지 모호할 수 있다.

객체지향 프로그래밍의 목적 중 하나인 캡슐화를 위해, 사용 용도가 같은 것들끼리 묶어서 관리할 필요가 있다.

 

#include<iostream>
using namespace std;

int simObjCnt = 0; // SoSimple 클래스에서 사용하는 전역 변수
int cmxObjCnt = 0; // SoComplex 클래스에서 사용하는 전역 변수

class SoSimple{
public:
    SoSimple(){
        simObjCnt++;
        cout << simObjCnt << "번째 SoSimple 객체" << endl;
    }
};

class SoComplex{
    public:
        SoComplex(){
            cmxObjCnt++;
            cout << cmxObjCnt << "번째 SoComplex 객체" << endl;
        }
        SoComplex(SoComplex &copy){
            cmxObjCnt++;
            cout << cmxObjCnt << "번째 SoComplex 객체" << endl;
        }
};

int main(void){
    SoSimple sim1;
    SoSimple sim2;

    SoComplex com1;
    SoComplex com2 = com1;
    SoComplex();
    return 0;
}

 

위 경우에 SoSimple 클래스와 SoComplex 클래스가 사용하는 전역 변수가 각각 다르다.

바깥에 따로 존재하게 된다면 실수로 값을 변경할 가능성이 높아진다.

따라서 이 변수를 클래스 내부에 집어넣되, 그 값을 전역변수로써 사용하고 싶다면, static 키워드를 사용하면 된다.

 

#include<iostream>
using namespace std;

class SoSimple{
private:
    static int simObjCnt; // 클래스 내부에 들어옴!
public:
    SoSimple(){
        simObjCnt++;
        cout << simObjCnt << "번째 SoSimple 객체" << endl;
    }
};

int SoSimple::simObjCnt = 0;

class SoComplex{
private:
    static int cmxObjCnt; // 클래스 내부에 들어옴!!
public:
    SoComplex(){
        cmxObjCnt++;
        cout << cmxObjCnt << "번째 SoComplex 객체" << endl;
    }
    SoComplex(SoComplex& copy){
        cmxObjCnt++;
        cout << cmxObjCnt << "번째 SoComplex 객체" << endl;
    }
};

int SoComplex::cmxObjCnt = 0;

int main(void){
    SoSimple sim1;
    SoSimple sim2;

    SoComplex cmx1;
    SoComplex cmx2 = cmx1;
    SoComplex();
    return 0;
}

 

위 코드를 보면 simObjCnt와 cmxObjCnt가 각각 SoSimple과 SoComplex 클래스 내부에 존재하는 것을 확인할 수 있다.

그냥 int 가 아닌 , static int를 사용하여, 객체 생성과 상관없이 클래스 당 하나만 존재하는 전역 변수가 만들어지는 것이다.

 

그리고 현재 static 변수들은 클래스의 private 영역에 있으므로 일반적인 변수와 동일하게 클래스 내의 함수로만 변경할 수 있다.

만약, public 영역에 존재한다면 클래스 외부에서도 접근이 가능하다!!!

 

 

 

추가적으로 설명하자면, SoSimple 클래스로 객체를 sim1, sim2, sim3를 생성한다면, 위처럼 객체별로 멤버 변수와 함수(함수도 엄밀히 나눠가지는 것은 아니다.)를 나눠가지지만, static 변수는 클래스당 하나만 생성되어 각 객체들이 공유하는 것을 확인할 수 있다.

 

결론적으로, 클래스 내에서 static 키워드를 사용하는 이유는, 클래스 내부에 전역 변수를 선언하여 관리하기 위함이다.

 

 

728x90
반응형
LIST

'C++' 카테고리의 다른 글

[C++] 상속  (0) 2024.06.30
[C++] 일반적인 전역 변수와 static 전역 변수의 차이점  (0) 2024.06.28
[C++] friend  (0) 2024.06.28
[C++] 복사 생성자 (Copy Constructor)  (0) 2024.06.27
[C++] malloc과 new 의 차이점  (0) 2024.06.25