static 변수에 대하여
1. Static
- 일단 전역변수, 하지만 접근에 지역적인 제한이 있다.
- 사용하려면 헤더가 아닌 실행부(cpp)에서 초기화를 해주어야 한다.
- OOP의 캡슐화를 지키면서 전역처럼 쓸수 있는 방법
2. class의 비밀
- class의 인스턴스를 생성하면 멤버변수들만이 독립적인 메모리에 할당되며 멤버 함수는 기존 클래스에 선언된 함수를 호출하여 사용한다.
- 그래서 클래스의 맴버함수들은 기본적으로 this를 인자로 받는다. 그리고 그걸 숨긴다.
void Point::printAge(){
printf("(%d, %d)", m_X , m_Y);
}
//이런 멤버함수는 모든 클래스가 공유하기 때문에 원래 컴파일러는 이 함수를 이렇게 번역한다.
void Point::printAge(Point& this){
printf("(%d, %d)", this->m_X , this->m_Y);
}
//공유되는 함수에 this를 받아서 사용한다는 것!
void Point::printAge(){
printf("(%d, %d)", m_X , m_Y);
}
//이런 멤버함수는 모든 클래스가 공유하기 때문에 원래 컴파일러는 이 함수를 이렇게 번역한다.
void Point::printAge(Point& this){
printf("(%d, %d)", this->m_X , this->m_Y);
}
//공유되는 함수에 this를 받아서 사용한다는 것!
3. 정적 멤버 변수
- 클래스의 모든 인스턴스들이 공유하는 멤버변수.
- 객체의 은닉성을 유지하면서 모든 인스턴스들이 접근할 수 있어야하므로 static으로 선언한다.
- 각 인스턴스에 귀속된 값이 아니므로 this.m_StaticMember 로 호출하기보다는 CClass::m_StaticMember로 호출하는 것이 더 알맞다.
- 객체가 생성되기 전에 이미 Static은 전역변수처럼 메모리가 할당되므로, 생성자에서 초기화해줄 수 없다.
- 일반적인 방식으로 헤더에 선언만 하고 cpp파일에서 별개로 선언 및 초기화하는 방식을 선택한다.
//예제코드
class CClass
{
private:
int Value;
static int m_Count; //정적 멤버 변수 인스턴스 아니고 클래스에 귀속
public:
//생성자와 소멸자에서 값을 변경하고 저장가능한것은 정적 멤버 변수이기 때문
CClass() { m_Count++; }//생성자 호출될 때 1개 증가
~CClass() { m_Count--; }//소멸자 호출될 때 1개 감소.
void OutNum() {
printf("현재 객체 개수 = %d\n",m_Count);
}
};
int CClass::Num=0; //클래스의 인스턴스가 생성되기 이전에 이미 메모리영역을 차지한다.
//예제코드
class CClass
{
private:
int Value;
static int m_Count; //정적 멤버 변수 인스턴스 아니고 클래스에 귀속
public:
//생성자와 소멸자에서 값을 변경하고 저장가능한것은 정적 멤버 변수이기 때문
CClass() { m_Count++; }//생성자 호출될 때 1개 증가
~CClass() { m_Count--; }//소멸자 호출될 때 1개 감소.
void OutNum() {
printf("현재 객체 개수 = %d\n",m_Count);
}
};
int CClass::Num=0; //클래스의 인스턴스가 생성되기 이전에 이미 메모리영역을 차지한다.
4. 정적 멤버 함수
- 인스턴스와 완전 상관없는 클래스 함수. 다른 멤버함수들이 내부적으로 this를 인자로 받는 반면, 정적 멤버 함수는 받지 않는다.
- 그러니까 이런 함수에서 this를 쓰면 안된다. 정적 멤버 아닌것들은 정적 멤버 함수에서 접근할 수 없다. 일반 멤버는 기본적으로 this->m_Member를 암시적으로 사용하기 때문이다.
- 호출할 때에도 정적 멤버 변수처럼 특정 인스턴스에서 호출하지 않고 클래스::정적함수 형식으로 호출한다.
class Count
{
private:
int Value;
static int Num;
public:
Count() { Num++; }
~Count() { Num--; }
static void InitNum() {
Num=0; //인스턴스가 하나도 없어도 호출할 수 있어야함.
}
static void OutNum() {
printf("현재 객체 개수 = %d\n",Num); //인스턴스와 별개로 클래스가 관리하는 함수.
}
};
int Count::Num;
class Count
{
private:
int Value;
static int Num;
public:
Count() { Num++; }
~Count() { Num--; }
static void InitNum() {
Num=0; //인스턴스가 하나도 없어도 호출할 수 있어야함.
}
static void OutNum() {
printf("현재 객체 개수 = %d\n",Num); //인스턴스와 별개로 클래스가 관리하는 함수.
}
};
int Count::Num;
5. 정적 멤버 활용
- 전체 프로그램에서 접근 가능하게
- 인스턴스가 아니라 클래스 자체를 다룰 필요가 있을 때
- 클래스에서 딱 한번만 해야하는 초기화(네트워크 연결, 윈도우 클래스 등록 등)를 정적 멤버함수로 빼면 편함.
- 클래스에 공통적으로 사용되는 자원, 정보가 필요할 때.
'컴퓨터 > C++' 카테고리의 다른 글
c++ 함수포인터 부터 std::function까지 (0) | 2015.03.10 |
---|---|
FSM과 State 패턴 (0) | 2015.03.10 |
c++의 여러가지 생성자들 (0) | 2015.03.10 |
c++의 가상함수 (0) | 2015.03.10 |