2016-10-25 2 views
5

:파괴 주문 다음 코드

class C { 
public:  
    static C& Instance() { 
     static C c; 
     return c; 
    } 

    ~C(){std::cout << "c destructed\n";} 
private: 
    C(){} 
}; 

class D{//similar to C but prints `d destructed` on destruction 
//... 

int main() 
{ 
    auto c = C::Instance(); 
    auto d = D::Instance(); 
} 
//outputs (with gcc) 
//d destructed 
//c destructed 
//d destructed 
//c destructed 

나는 몇 가지 질문이 있습니다

  1. 이 파괴의 순서가 잘 정의 된 호출되어 있습니까? (클래스 C와 D가 다른 소스 파일에 정의 된 경우에도)
  2. 잘 정의 된 경우이 동작은 휴대용입니까?
+0

내가 표준 실제로 그것을 정의라고 생각하지 않는다 객체 들로서 그들은 역순으로 파괴 되어야만하는 것인가? –

+0

파괴 순서는 단일 [번역 단위] (https://en.wikipedia.org/wiki/Translation_unit_ (프로그래밍)) 내에서 잘 정의되어있다. 그러나 번역 단위 사이에는 존재하지 않습니다. –

+0

[관련 질문 및 답변] (http://stackoverflow.com/q/246564/440558). –

답변

7

이 구조의 포인트가 건설 순서를 부과하는 것입니다 : 당신이 C 싱글을 확인하려는 경우 D 싱글이 파괴 된 후, 당신은 D에 shared_ptr을 < C>를 저장할 수있을 때까지 예를 들어, 유효 (따라서 파기 명령).

건설

이러한 로컬 정적 변수이므로

이 구성의 순서는 각 Instance 기능이 처음으로 호출하는 순서에 의해 결정된다.

main에서 완료되었으므로 제작 순서가 완전히 지정됩니다.

순서가 지정되지 않은 만들 수있는 유일한 방법은 하나

C& the_c = C::Instance(); 

이있는 경우는 예를 들어, 다른 번역 단위로 정적 초기화에서 사용할 경우이고 다른 하나는

D& the_d = D::Instance(); 

파괴를 가지고

정적 저장소를 사용하여 개체가 파괴되는 것은 건설 순서와 반대입니다.

3.6.3, 종단, 제 1

생성자 또는 정적 저장 기간을 갖는 개체의 동적 초기화의 완성 서로 소멸자의 완성의 앞에 순서화되면 두 번째는 첫 번째의 소멸자가 시작되기 전에 으로 시퀀싱됩니다.

따라서 파괴 순서는 공사 순서에 따라 완전히 지정됩니다.

번역 단위에 관계없이이 중 하나가 다른 하나에 종속되어 있어도이 단일 구조가 잘 지정되어 있습니다.이다

이 완벽하게 안전하고, 정의 어디에 문제가되지 않습니다 : 그것은 세계의 파괴 순서를 정의하지 않는 한

class C { 
public:  
    static C& Instance() { 
     static C c(D::Instance()); 
     return c; 
    } 

    ~C(){ m_d.doSomething(); } // Yes, this is safe. 
private: 
    C(D& d) : m_d(d) { m_d.doSomething(); } // Yes, this is safe. 
    D& m_d; 
}; 
-1

일반적으로 정적 로컬 변수 (귀하의 경우에 사용됨)를 비롯한 정적 개체의 삭제 순서는 정의되지 않습니다.

파괴 순서를 보장하기 위해 내가 사용한 패턴 중 하나는 std :: shared_ptr을 활용하는 것입니다.

class C { 
    static shared_ptr<C> Instance() { 
    static auto c = make_shared<C>(); 
    return c; 
    } 
}; 

class D { 
    static shared_ptr<D> Instance() { 
    static auto d = make_shared<D>(); 
    return d; 
    } 

    D(): c_(C::Instance()) {} 

private: 
    shared_ptr<C> c_; 
}; 
+0

[molbdnilo의 대답] (http://stackoverflow.com/a/40243538/4115625)는 파괴 순서를 설명하고 -1 – Danh