2009-09-09 2 views
1

소프트웨어 개발자로서 처음으로 일을 시작했을 때 PDF 문서와의 C++ 값 (또는 객체)을 쓰고 읽을 수있는 시스템을 만들었습니다. 이것은 타입을 id로 그리고 그 반대로 매핑하는 시스템이 필요했습니다. 코드베이스는 거대했고 여러 가지 '레이어'코드 (기본 프레임 워크 레이어, 도구 레이어, 뷰 레이어 등)가있었습니다. 제안 된 솔루션은 특정 레이어에 정의 된 유형에 대한 ID가 포함 된 enum을 사용하여 각 레이어에 헤더 파일을 추가하는 것이 었습니다. 충돌을 피하기 위해 각 열거 형의 첫 번째 값은 오프셋 값 (1000, 2000, 3000, ...)으로 시작합니다. 이 시스템은 나에게 조금 서투른 것 같았다으로 다른 컴파일 단위에서 액세스 할 수있는 정적 변수에 문제가있을 수 있습니까?

나는 다른 무언가를 시도하기로 결정하고, 고유 ID 나타 내기위한 클래스를 내놓았다 대신 열거의

// UniqueId.h 
class UniqueId 
{ 
public: 
    UniqueId(); 

    operator int() const; 

private: 
    int mId; 
    static int sCounter; 
}; 

// UniqueId.cpp 
int UniqueId::sCounter = 0; 

UniqueId::UniqueId() 
{ 
    mId = ++sCounter; 
} 

UniqueId::operator int() const 
{ 
    return mId; 
} 

, UNIQUEID 객체의 이제 단순히 목록을 수 상충되는 ID를 두려워하지 않고 만들 수 있습니다.

내 코드를 검토하는 사람 (회사의 소프트웨어 아키텍트)이 처음에 이것을 동의했습니다. 그러나 하루가 지나면 그는 마음이 바뀌었고이 시스템이 작동하지 않을 것이라고 말했다. 저는 여러 편집 단위로 인해 문제가있을 것이라고 언급하면서 그를 모호하게 기억합니다.

오늘, 약 4 년 후, 나는 아직도 그 문제가 무엇인지 이해할 수 없다. 내가 아는 한, 정적 변수는 하나의 컴파일 단위 (UniqeId.cpp의 경우)에서만 정의됩니다.

그래서 .. StackOverflow가 베테랑 개발자와 매우 풍부하기 때문에 몇 가지 설명을 요청할 기회를 원합니다. 이것이 실제로 문제가 되었습니까? 아니면 제 생각이 옳았습니까?

답변

4

"유형"에 다른 ID를 할당하는 것이 중요합니까? 너의 프로그램? 그렇지 않다면 모든 것이 잘되어야합니다. 그렇다면 ...

ID가 다른 "유형"은 무엇입니까? 한 가지 방법이 될 수 있습니다

class FooType 
{ 
private: 
    static UniqueId myId; 
... 
}; 

이 프레드 라슨가 연결된 static initialization order fiasco를 호출합니다. statics의 초기화 순서는 정의되어 있지 않으므로 빌드에서 빌드로 myId에 다른 값을 할당하거나 실행 중에 실제로 불행한 경우 다른 값을 할당 할 수 있습니다.

대신 객체의 생성자 또는 정적 변수가있는 메소드로 필요한 경우에만 UniqueId의 인스턴스를 만들 수 있습니다. 예 :

class BarType 
{ 
private: 
    const UniqueId &getMyId() 
    { 
     static UniqueId myId; 
     return myId; 
    } 
    .... 
}; 

이제 다중 스레드 프로그램을 개발할 때 스레드 안전성에 대해 걱정할 필요가 있습니다. 그 외에도 UniqueId 값은 프로그램의 흐름에 크게 의존하며, 실행에 따라 변경 될 가능성이 큽니다.프로그램을 한 번 실행하면 BarType을 인스턴스화 할 필요가 없으므로 ID를 요구하지 않습니다. 다른 실행에서는 일찍 BarType이 필요할 수 있습니다. 다른 경우에는 나중에 BarType이 필요할 수 있습니다.

이 설정에 대해 모두 잊어 버리기 전까지는 모든 빌드가 올바르게 작동 할 수도 있습니다. 누군가는 새로운 "유형"을 추가하거나 기존 유형 중 일부를 저글링하거나 전혀 관련이없는 변경을하게됩니다. 그런 다음 갑자기 모든 것이 위에 열거 된 이유 중 하나로 인해 중단됩니다.

+1

ID가 다른 실행간에 동일 할 필요는 없습니다. 좋은 질문. 우리가 파일에 ID를 쓸 필요가있는 경우에 문제가되었을 수도 있습니다 ... – StackedCrooked

+0

이 경우 큰 실패는 다른 ID 값을 다른 빌드로 가져 오는 최악의 문제로 이어질 수 있다고 생각합니다. ID 카운터의 초기화는 일부 ID가 이미 발행 된 후에 발생할 수 있으며 중복 ID가 발생할 수 있습니다. –

+0

@FredLarson, ID 카운터가 나중에 초기화되면 이전에 유형에 대해 발행 된 값이 정의되지 않았 음을 의미합니다. 맞습니까? 당신이 제공 한 링크를 통해 갈 것이지만, 당신이 나를 위해 이것을 명확히 할 수 있다면 고맙겠습니다. – batbrat

4

아마도 그는 Static Initialization Order Fiasco을 언급했을 것입니다.

여기에 게시 한 내용으로는 문제가 표시되지 않습니다. 다른 번역 단위의 정적 변수에 의존하여 큰 문제가 발생해야합니다.

1

코드가 나에게 잘 보이고 시스템의 모든 "레이어"에 예약 된 값을 가진 열거 형보다 명확하게 좋습니다. 이런 식으로 통계학을 사용하는 데 문제가 있었지만 해결책이있었습니다. GUID. 당신은 정말로 괜찮다고 생각합니다. 소프트웨어 아키텍트는 임금이 인상 된 개발자의 멋진 이름 일 뿐이라는 것을 기억하십시오. 그는 자신보다 숙련 된 사람이 아닙니다.)

관련 문제