수색…


비고

노동 조합은 매우 유용한 도구이지만 몇 가지 중요한주의 사항이 있습니다.

  • C ++ 표준에 따라 가장 최근에 수정 된 구성원이 아닌 공용 구조체의 요소에 액세스하는 것은 정의되지 않은 동작입니다. 많은 C ++ 컴파일러가 잘 정의 된 방식으로이 액세스를 허용하지만, 이것은 확장이며 컴파일러에서 보장 할 수 없습니다.

    std::variant (C ++ 17부터)는 유니온과 비슷하지만 현재 들어있는 내용을 알려줍니다 (보이는 상태의 일부는 주어진 순간에 보유하는 값의 유형입니다 : 값 액세스 만 발생하도록 강제합니다 그 유형에).

  • 구현에 따라 크기가 다른 회원을 같은 주소로 정렬 할 필요는 없습니다.

기본 연합 특징

공용체는 모든 멤버가 겹치는 메모리를 차지하는 특수 구조체입니다.

union U {
    int a;
    short b;
    float c;
};
U u;

//Address of a and b will be equal
(void*)&u.a == (void*)&u.b;
(void*)&u.a == (void*)&u.c;

//Assigning to any union member changes the shared memory of all members
u.c = 4.f;
u.a = 5;
u.c != 4.f;

일반적인 사용

공용체는 혼합 데이터 유형을 구현할 때와 같이 독점 데이터에 대한 메모리 사용을 최소화하는 데 유용합니다.

struct AnyType {
    enum {
        IS_INT,
        IS_FLOAT
    } type;
    
    union Data {
        int as_int;
        float as_float;
    } value;

    AnyType(int i) : type(IS_INT) { value.as_int = i; }
    AnyType(float f) : type(IS_FLOAT) { value.as_float = f; }

    int get_int() const {
        if(type == IS_INT)
            return value.as_int;
        else
            return (int)value.as_float;
    }
    
    float get_float() const {
        if(type == IS_FLOAT)
            return value.as_float;
        else
            return (float)value.as_int;
    }
};

정의되지 않은 동작

union U {
    int a;
    short b;
    float c;
};
U u;

u.a = 10;
if (u.b == 10) {
   // this is undefined behavior since 'a' was the last member to be
   // written to. A lot of compilers will allow this and might issue a
   // warning, but the result will be "as expected"; this is a compiler
   // extension and cannot be guaranteed across compilers (i.e. this is
   // not compliant/portable code).
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow