티스토리 뷰
목차
[C++강좌 리팩토링] 메모리 최적화, Unions 이용
Unions 또한 리팩토링과 메모리 낭비를 막기 위해 사용할 수 있다. 데이터 멤버 중 (최소한) 하나라도 활성화되면 같은 메모리 공간에 모든 데이터 멤버가 위치하기 때문이다.
union은 데이터 멤버를 모두 저장할 수 있으며, 생성자와 소멸자를 포함할 수 있다. 하지만 가상 멤버 함수를 가질 순 없다.
union은 다른 클래스의 기저 클래스로써 사용될 수 없으며 다른 클래스로부터 상속할 수도 없다.
union은 비자명한 특수 멤버 함수들을 가지는 객체들을 저장할 수 없다.
C++에서는 익명의(anonymous) unions을 지원한다. anonymous union은 이름이 없는 객체이다.
예를 들면, 명명된 union과는 다르게 익명의 union은 멤버 함수나 nonpublic 데이터 멤버들을 가질 수 없다.
1 2 3 | union { long n; void * p}; // 익명 n = 1000L; // 멤버들은 직접적으로 액세스됨 p = 0; // n은 이제 0임 | cs |
[C++강좌 팁] unions은 언제 유용한가?
다음의 클래스는 데이터베이스로부터 person의 데이터를 추출한다.
키(key)는 고유한 ID 번호이거나 person의 성(last name)이 될 수 있지만 둘 다 될 수는 없다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | class PersonalDetails { private: char * name; long ID; //... public: // key is of type char * used PersonalDetails(const char *nm); //numeric key used PersonalDetails(long id) : ID(id) {} }; | cs |
여기에서 낭비되는 메모리는 무엇일까?
[C++강좌 리펙토링] 메모리 최적화, Unions 이용
이유는 key는 2개이지만 한 번에 사용할 수 있는 멤버는 하나 뿐이기 때문이다. (char, long)
익명의 union은 이런 경우에 메모리 사용을 최소화하기 위해 사용될 수 있다.
예를 들면,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class PersonalDetails { private: union //anonymous { char * name; long ID; }; public: PersonalDetails(const char *nm); //멤버에 대한 직접적인 액세스 PersonalDetails(long id) : ID(id) {/**/} //... }; | cs |
union을 사용함으로써 클래스 PersonalDetails의 크기는 반으로 줄어든다.
[C++강좌 리펙토링] 메모리 최적화, Unions 이용
다시, 4바이트의 메모리를 절약하는 것은 이들 클래스가 수 백만 개의 데이터베이스 레코드들의 주형(mold)으로서 사용되지 않는 한 또는 레코드들이 느린 통신선로들을 통해 전송되지 않는 한 일부러 수고할 가치가 없다.
unions은 실행시간 오버헤드를 초래하지 않으며, 늘어지는 속도tradeoff도 존재하지 않는다는 것에 주목하라. 명명된 union에 대한 익명 union의 장점은 멤버가 직접적으로 액세스 될 수 있다는 것이다. 오버로드된 postfix ++은 두 가지 이유에서 prefix보다 훨씬 덜 효율적이다. (임시적인 사본의 생성을 요구하며, 그 사본을 값에 의해 반환한다)
그러므로, 당신이 객체의 postfix 및 prefix 연산자들 사이에서의 선택이 자유로울 땐 prefix 버전을 선택하는 것이 좋다.
[C++강좌 리팩토링] 메모리 최적화, Unions 이용