티스토리 뷰

목차

    반응형

    [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 이용

    반응형