아마 팀 리더가 구현 싱글 대해 이야기 :
T &get_value() {
static T val;
return val;
}
를이 경우, 표준이 보증을 제공합니다.
구현이있다 : 첫 번째는 val
개체 즉 여러 스레드 6.7/4
에서 동시에 발생하는 경우에도, 정확히 한번 프로그램 실행의 흐름은 로컬 정적 변수의 선언을 통과 처음 구성 될 것이라는 것이다 구현시 네임 스페이스 범위 (3.6.2)에서 정적 또는 스레드 저장 기간을 사용하여 변수를 정적으로 초기화 할 수있는 것과 동일한 조건에서 정적 또는 스레드 저장 기간을 사용하여 다른 블록 범위 변수의 초기 초기화를 수행 할 수 있습니다. 그렇지 않으면 이러한 변수는 처음 제어가 선언을 통과 할 때 초기화됩니다. 그러한 변수는 초기화 완료시 초기화 된 것으로 간주됩니다. 예외를 throw하여 초기화가 끝나면 초기화가 완료되지 않으므로 다음에 컨트롤이 선언에 들어올 때 다시 시도됩니다. 변수가 초기화되는 동안 컨트롤이 동시에 선언에 들어가면 동시 실행은 초기화 완료를 기다려야합니다.
정적 초기화는이 경우에, 당신은 걱정하지해야 constexpr
생성자가없는 너무 오래 T
로, 상수의 경우에 허용 (단, 전체 규칙 3.6.2 읽기 코드와 관련된 일부 엣지 케이스).
제 보장 정적 저장 기간이 모든 변수들은 구조 3.6.3/1
의 역순으로 파괴 될 것이라는 것이다 : 초기화 된 개체
소멸자 (12.4) (즉,) (그 수명 3.8 개체 std :: exit (18.5)를 호출 한 결과 정적 저장소 기간이있는 저장소가 시작된 경우 (main에서 반환 한 결과로 호출 됨). 지정된 thread 내의 thread 스토리지 존속 기간을 가지는 초기화 된 오브젝트의 소멸자는, 그 thread의 초기 함수로부터 돌아 왔을 때, 및 그 thread가 std :: exit를 호출 한 결과로서 불려갑니다. 스레드 내에서 스레드 저장 기간을 가진 초기화 된 모든 객체에 대한 소멸자의 완료는 정적 저장 기간이있는 객체의 소멸자가 시작되기 전에 순서가 지정됩니다. 생성자의 완료 또는 스레드 저장 기간이있는 객체의 동적 초기화가 다른 스레드보다 먼저 시퀀싱되면 두 번째 소멸자의 완료는 첫 번째 소멸자의 초기화 전에 시퀀싱됩니다. 정적 저장 기간을 가진 객체의 생성자 완료 또는 동적 초기화가 다른 객체보다 먼저 시퀀싱되면 두 번째 소멸자의 완료는 첫 번째 소멸자의 초기화 전에 시퀀싱됩니다.[주의 :이 정의는 동시 파괴를 허용한다. - end note] 객체가 정적으로 초기화되면 객체가 동적으로 초기화 된 것과 같은 순서로 객체가 파괴됩니다. 배열 또는 클래스 유형의 객체의 경우 해당 객체의 모든 하위 객체가 파괴되어 하위 객체의 생성 중에 정적 저장 기간이 초기화 된 블록 범위 객체가 파기됩니다. 정적 또는 스레드 저장 기간을 가진 객체의 파기가 예외를 통해 종료되면 std :: terminate가 호출됩니다 (15.5.1).
이 단락은 동시 생성시 정적 객체를 동시에 파괴 할 수있는 범위가 많이 있지만, 파괴의 주된 이유는 파괴가 역순으로 발생한다는 것입니다. 함께
는, 이러한 평균은
T val
이 단일 기능의 또 다른 몇 가지
U val
에 따라 달라집니다 경우
U val
항상
T val
전에 구성과
T val
후 파괴된다는 것을 의미합니다, 그래서 전반적으로,이 (하지 않는 한 싱글 톤을 구현하는 안전한 방법입니다 당신은 매우 미친 짓하고 있어요).
* 싱글 톤 *에 대한 * 데드 레퍼런스 문제는 무엇입니까? 끔찍한 고통처럼 들리네. C++ 11에서는 함수 내에서 정적 변수의 생성이 스레드 세이프 (threadafe safe)가 될 것이라는 보증을 추가했으며, 처음에는 함수가 호출 될 때 생성됩니다. 이것은 아마도 당신이 찾고있는 것입니다. – Praetorian
나는 현재 문제의 제목을 6.5 절에서 언급 한 책과 같은 제목으로 사용하고있다. 책과 같은 제목을 사용하는 것이 더 나을 것 같아서 미안해. 나쁘게 들리더라도 내 가난한 영국인도 영어를 할 수있어. –