본문 바로가기
C++ 200제/코딩 IT 정보

[C++강좌 리팩토링] 메모리 최적화, Unions 이용

by vicddory 2017. 10. 2.

[C++강좌 리팩토링] 메모리 최적화, Unions 이용


Unions 또한 리팩토링과 메모리 낭비를 막기 위해 사용할 수 있다. 데이터 멤버 중 (최소한) 하나라도 활성화되면 같은 메모리 공간에 모든 데이터 멤버가 위치하기 때문이다.


union은 데이터 멤버를 모두 저장할 수 있으며, 생성자와 소멸자를 포함할 수 있다. 하지만 가상 멤버 함수를 가질 순 없다.

union은 다른 클래스의 기저 클래스로써 사용될 수 없으며 다른 클래스로부터 상속할 수도 없다.

union은 비자명한 특수 멤버 함수들을 가지는 객체들을 저장할 수 없다.


C++에서는 익명의(anonymous) unions을 지원한다. anonymous union은 이름이 없는 객체이다.


예를 들면, 명명된 union과는 다르게 익명의 union은 멤버 함수나 nonpublic 데이터 멤버들을 가질 수 없다.


1
2
3
union { long n; void * p}; // 익명
= 1000L; // 멤버들은 직접적으로 액세스됨
= 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++ Union, C++강좌 리펙토링[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++ 강좌, C++ 메모리 최적화[C++강좌 리펙토링] 메모리 최적화, Unions 이용


다시, 4바이트의 메모리를 절약하는 것은 이들 클래스가 수 백만 개의 데이터베이스 레코드들의 주형(mold)으로서 사용되지 않는 한 또는 레코드들이 느린 통신선로들을 통해 전송되지 않는 한 일부러 수고할 가치가 없다.


unions은 실행시간 오버헤드를 초래하지 않으며, 늘어지는 속도tradeoff도 존재하지 않는다는 것에 주목하라. 명명된 union에 대한 익명 union의 장점은 멤버가 직접적으로 액세스 될 수 있다는 것이다. 오버로드된 postfix ++은 두 가지 이유에서 prefix보다 훨씬 덜 효율적이다. (임시적인 사본의 생성을 요구하며, 그 사본을 값에 의해 반환한다)


그러므로, 당신이 객체의 postfix 및 prefix 연산자들 사이에서의 선택이 자유로울 땐 prefix 버전을 선택하는 것이 좋다.


[C++강좌 리팩토링] 메모리 최적화, Unions 이용

댓글