-
정적객체의 종류@ 16. 1 ~ 17. 1/면접관련 2017. 1. 5. 00:36
정적 객체(static)는 자신이 생성된 시점부터 프로그램이 끝날 때까지 살아 있는 객체
(애초에 스택객체, 힙 기반 객체는 될 수가 없다.)
정적 객체도
비지역 정적 객체(4가지 경우)와
(1 전역객체, 2 네임스페이스 유효범위에서 정의된 객체, 3 클래스 안에서 static으로 선언된 객체,
4 파일 유효범위에서 static으로 정의된 객체)
지역 정적개체로(1가지)나뉜다.
(5 함수 안에서 static으로 선언된 객체)
총 다섯 종류가 된다.
아래처럼 다른 소스cpp에 정의된 비지역 정적 객체를 직접적으로 서로 사용하는 짓거리는 하지말자..
a.cpp 또는 a.h
class A
{
public:
......
}
extern A aa; //전역 변수로 설정!!! 이게 위험 이건 이게 비지역 정적객체라고 한다!
extern은 외부에서 쓸 수 있게 하는 것..
class B
{
public:
B:B() { int num = aa.GetNum(); } //이런식으로 aa객체를 사용하는 행위는 안된다!
}
왜냐면 비지역 정적 객체들의 초기화 순서는 정해져 있지 않다.
보통 사용을 안하면 되지만 해결 방법도 있다.
1. 비지역 정적 객체를 하나씩 맡는 함수를 준비하고 이 안에 각 객체를 넣는것이다.
2. 함수속에서도 이들은 정적 객체로 선언하고 그 함수에서는 이들에 대한 참조자를 반환하게 한다.
3. 사용자 쪽에서는 비지역 정적 객체를 직접 참조하는 과거의 폐단을 버리고 함수 호출로 대신하게 된다.
결국 이렇게 하면 비지역 정적 개체가 지역 정적 객체로 바뀐것이다.(아까 정적객체는 두 종류가 있다고 했다)
왜 지역 정적 객체로 하냐면..지역 정적 객체는 함수 호출 중에 그 객체의 정의에 최초로 닿았을 때 초기화되도록 만들어져 있다. 그래서 위에 3번을 하게 되면 반드시 초기화된 객체를 참조하도록 된다.
그리고 4. 새롭게 준비한 이 지역정적객체의 함수를 호출할 일이 없다면 해당 객체의 생성, 소멸 비용도 생기지 않게 막아야 한다.
(싱글톤? 맞다 싱글톤 패턴)
아까 위에 A, B클래스를 위에 4가지에 맞게 변경하면
class A
{
A& aa()
{
static A aa; //지역 정적객체로 정의하고 초기화까지!!
return aa; //반환!!
}
}
class B
{
B:B() { int num = aa().GetNum(); //aa에서 aa()로 변경되었다!
}
이 함수의 호출빈도가 잦다면 인라인하는게 낫다. (지극히 단순하니까..)
그.러.나 다중 스레드에선 지역 객체이든 비지역 객체이든 시한폭탄이 된다.
어쨌든 위에 방법은 객체들의 초기화 순서를 제대로 맞춰 둔다는 전제조건이 뒷받침이 되어야 한다. 이를 테면 객체 B가 초기화되기 전에 객체 A가 초기화되어야 하는데 A가 B에 의존한다면..이건....
'@ 16. 1 ~ 17. 1 > 면접관련' 카테고리의 다른 글
힙 자료구조 추가 설명 (0) 2017.01.05 원형큐 / 해시테이블 의사코드 정리 (0) 2017.01.05 객체 생성 및 소멸자에 절대로 가상 함수 호출금지 (0) 2017.01.05 컴파일과정 정리 / cpp와 h를 나누는 이유? (1) 2017.01.04 rand()함수보완 및 클래스 메서드와 데이터 멤버에 대한 포인터?? (0) 2017.01.04