문제

나는 깃발로 프로그래밍하는 데별로 익숙하지 않지만 방금 유용한 상황을 발견했다고 생각합니다.

특정 이벤트의 청취자로 등록하는 몇 가지 물체가 있습니다. 그들이 등록하는 이벤트는 건설 될 때 전송되는 변수에 따라 다릅니다. 이 작업을 수행하는 좋은 방법은 다음과 같이 비트 또는 연결된 변수를 보내는 것입니다. 잡기 가능 | 액체 등. 그러면 생성자에서 물체는 어떤 플래그를 설정했는지 확인하고 그 자체를 자체적으로 등록 할 수 있습니다.

그러나 이것은 내가 혼란스러워하는 곳입니다. 바람직하게는 깃발이 열거적 일 것이다. 그러나 그것은 또한 문제이기도합니다. 이 깃발이 있다면 :

enum
{
    TAKES_DAMAGE,/* (0) */
    GRABBABLE, /* (1) */
    LIQUID, /* (2) */
    SOME_OTHER /* (3) */
};

그런 다음 깃발을 보내면 some_other (3)를 보내는 것과 동일합니다. 액체, 그렇지 않습니까?

이 물건을 정확히 어떻게 처리합니까?

도움이 되었습니까?

해결책

열거는 두 가지의 힘이어야합니다.

enum
{
    TAKES_DAMAGE = 1,
    GRABBABLE = 2,
    LIQUID = 4,
    SOME_OTHER = 8
};

또는보다 읽기 쉬운 방식으로 :

enum
{
    TAKES_DAMAGE = 1 << 0,
    GRABBABLE = 1 << 1,
    LIQUID = 1 << 2,
    SOME_OTHER = 1 << 3
};

왜요 ? 깃발을 겹치지 않고 결합하고이를 수행 할 수 있기를 원하기 때문입니다.

if(myVar & GRABBABLE)
{
    // grabbable code
}

... 열거 값이 다음과 같이 보이는 경우 작동합니다.

 TAKES_DAMAGE: 00000001
 GRABBABLE:    00000010
 LIQUID:       00000100
 SOME_OTHER:   00001000

그래서 당신이 설정했다고 말합니다 myVar 에게 GRABBABLE | TAKES_DAMAGE, 여기에 grabbable 깃발을 확인해야 할 때 작동하는 방법은 다음과 같습니다.

 myVar:     00000011
 GRABBABLE: 00000010 [AND]
 -------------------
            00000010 // non-zero => converts to true

당신이 설정했다면 myVar 에게 LIQUID | SOME_OTHER, 작업은 다음과 같습니다.

 myVar:     00001100
 GRABBABLE: 00000010 [AND]
 -------------------
            00000000 // zero => converts to false

다른 팁

깃발을 저장하는 또 다른 방법은 기본 유형을 전혀 귀찮게하지 않는 것입니다. 열거를 사용하는 경우, 열거 값은 기본적으로 서명되지 않은 INT로 저장되며, 이는 공통 컴퓨터에서 32 비트입니다. 이것은 당신에게 32 개의 가능한 깃발 만 제공합니다. 확실히 많이, 충분하지 않은 경우가 있습니다.

이제 플래그 세트를 다음과 같은 방식으로 정의 할 수 있습니다.

typedef struct
{
    int takes_damage : 1;
    int grabbable    : 1;
    int liquid       : 1;
    int some_other   : 1;
} flags;

이 문제가 발생하지 않으면 ': 1'부분은 컴파일러에게 1 비트 만 사용 하여이 구조물 멤버를 저장하도록 지시합니다.

이제 플래그를 보유 할 변수를 정의하고 해당 깃발과 함께 작업 할 수 있습니다.

flags myflags = {1,0,0,1}; // defines a variable holding a set of flags, with an initial value of takes_damage & some_other

myflags.liquid = 1; // change the flags to include the liquid

if ( myflags.takes_damage ) // test for one flag
    apply_damage();
if ( myflags.liquid && myflags.some_other ) // test for multiple flags
    show_strange_behavior();

이 방법을 사용하면 제한없이 깃발을 여러 플래그를 정의 할 수 있으며 오버플로를 두려워하지 않고 언제든지 깃발 세트를 확장 할 수 있습니다. 단점은 플래그의 서브 세트를 테스트하는 것이 더 번거롭고 더 많은 코드가 필요하다는 것입니다.

예. 대신, 열거 회원의 힘을 2 :

enum
{
    TAKES_DAMAGE = (1 << 0),
    GRABBABLE = (1 << 1),
    LIQUID = (1 << 2),
    SOME_OTHER = (1 << 3)
};

플래그는 두 가지만 전원을 만들어야합니다. 즉, 각각이 저장하는 데이터 유형에 약간 이루어지며, 비트 또는 비트를 할 때는 아무것도 겹치지 않습니다.

열거에서 값을 설정할 수 없습니까?

enum {
 TAKES_DAMAGE = 1,
 GRABBABLE    = 2,
 LIQUID       = 4
}

그 후, 그냥 조금씩 또는 그들에게 성능을 발휘합니다.

당신은 필요합니다

enum
{
    TAKES_DAMAGE = 1,
    GRABBABLE = 2,
    LIQUID = 4,
    SOME_OTHER = 8
};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top