2014-12-02 3 views
1

const 정적 문자열 클래스 멤버의 초기화 순서에 문제가 있습니다. 일부 코드 :const 정적 멤버 초기화 순서를 보장하려면 어떻게해야합니까?

constants.h 고전 const를 정적 초기화합니다 (getInstance 무시)입니다

class Constants 
{ 
public: 
    // not used right now 
    Constants& getInstance(); 

    const static std::string CONST_STRING; 
}; 

constants.cpp

const std::string Constants::CONST_STRING = "my string"; 

Constants& Constants::getInstance(); 
{ 
    static Constants c; 
    return c; 
} 

. 나는 다음과 같은 또 다른 번역 단위에서 다른 곳이 상수를 사용하려고하는 경우에는 :

class OtherClass 
{ 
public: 
    OtherClass() 
    { 
     // tried uncommenting next line 
     // Constants::getInstance(); 
     std::string str(Constants::CONST_STRING); 
     std::cout << str; 
    } 
} 

OtherClass obj; // note global 

CONST_STRING

즉, 비어가 구축하지만, 초기화되지되었습니다. 전역 초기화 순서가 변환 단위에 정의되어 있지 않고 여기에 적용되는 것과 같은 것을 추측하고 있습니다.

그러나 Constants가 사용되기 전에 완전히 구성되어 있는지 확인하려고하는 주석 처리 된 행을 제거하면 (필자는 필요 없다고 생각하지만 그것을 제공합니다 ....) 여전히 문제가 해결되지 않습니다.

질문 :

  • 어떻게 사람이 그들을 사용하려고하기 전에 const를 정적 멤버가 완전히 초기화되도록 할 수 있습니까?
  • 이것은 클래스와 관련된 상수를 갖는 최상의 C++ 11 방법입니까? constexpr 여기에 사용할 수있는 것이 있습니까? @AndreyT는 수준의 초기화를 가질 수 있습니다 정적, 문자 타입을 const 지적

    const std::string & GetConstantsString(){ 
        static const std::string CONST_STRING = "My string"; 
        return CONST_STRING; 
    } 
    

    그래서 내 옵션 # 1이되지 않습니다

+3

당신의 상수는 싱글 톤 패턴을 구현하는 것 - 당신을 통해 문자열에 액세스 할 수 있도록하지 않는 이유를 싱글 톤? 즉, 문자열을 멤버로 만들고 싱글 톤 생성자에서 초기화합니다. – BeyelerStudios

+0

정적 초기화 순서 실패에 대한 [this C++ FAQ 항목] (http://www.parashift.com/c++-faq/static-init-order-on-first-use.html)을 참조하십시오. – cdhowie

+0

'getInstance()'는'CONST_STRING'의 초기화에 영향을주지 않습니다. 그리고'constexpr'은'basic_string' 생성자가'constexpr'이 아니기 때문에 옵션이 아닙니다. 특정 순서를 보장하려면,'CONST_STRING' 함수를'static std :: string' 함수에'const '를 반환하는 함수로 만들 수 있습니다. – Praetorian

답변

1

은 어쩌면 이것은 당신이 찾고있는 무엇 work

+0

옵션 1이 작동한다고 생각하지 않습니다. 옵션 1이 작동한다고해도 문제가 해결되지 않습니다. 그리고 옵션 2의 리턴 타입은'std :: string const &'이어야합니다. – Praetorian

+0

Er ... 리터럴 타입 * const 정적 멤버 만 클래스 내 초기화자를 가질 수 있습니다. 'std :: string'는 리터럴 타입이 아닙니다. 귀하의 "첫 번째 옵션"은 해당 언어에 존재하지 않습니다. – AnT

+0

@cdhowie 감사합니다. – Quest

1

번역 단위 내의 전역 (global) 초기화가 해당 번역 단위 내의 숨겨진 코드에서 발생합니다. 숨겨진 코드 비트가 호출 될 순서를 제어 할 수 없습니다.

기본 데이터 유형

상수가 아니라 실행 시간보다 컴파일시에 초기화 할 수 있습니다, 그래서이 작동합니다 :

const char Constants::CONST_STRING[] = "my string"; 
관련 문제