2012-08-02 6 views
2

내가 있다고 가정 클래스 A, B 및 C생성자 초기화 세트를 통해 초기화 된 변수의 파기 순서는 무엇입니까?

내가 즉, 컨테이너의 소멸자를 호출하는 경우 이제

Container::Container() 
:A(10),B(20),C(30) 
{ 
    //Do something specific 
} 

을 다음과 같이 난 후 용기가 있다면 ~ 컨테이너() 나는 소멸자를 받고 있는지 알 역순으로 호출 됨 ~ C(), ~ B(), ~ A()

이 순서는 항상 고정 된 순서입니까? 건설 초기화를위한 소멸자의 순서에 대해 더 많은 빛을 던질 수 있습니까?

답변

7

순서는 고정되어 있지만 초기화 목록에서는 고정되어 있지 않습니다.

멤버가 클래스에서 선언 된 것과 반대입니다. Container 객체가 소멸

class Container 
{ 
    A a; 
    B b; 
    C c; 
}; 

, 회원이 삭제되는 순서는 c, ba이다.

일부 컴파일러는 멤버를 선언 된 순서와 다른 순서로 초기화하면 경고를 표시하며 일관성을 유지하는 것이 좋습니다.

+0

네, 지금 받으십시오. 따라서 선언/초기화 순서의 순서를 뒤집어 쓰면 파괴 순서가 엉망이 될 수 있습니다. 선언과 초기화간에 일관성을 유지하는 것이 좋습니다. 나는이 규칙에 대해 알고 있었지만 건설 초기화에도 적용된다는 것을 알지 못했다. – rajshenoy

+0

@rajshenoy 잘, 파괴의 순서는 바뀌지 만 엉망이 아닙니다. 그것은 여전히 ​​잘 정의되어있을 것입니다. :) –

+0

@rajshenoy 예, 예를 들어 b와 c를 교환하면 b가 먼저 파괴됩니다. –

6

그들은 항상 구조의 역순으로 파괴됩니다. 초기화 순서는 초기화 목록의 순서와 관계없이 항상 선언 순서입니다.

3

구성원 (및 비 가상 하위 개체)은 선언 된 순서대로 구성되며 반대 순서로 소멸됩니다. 이니셜 라이저 목록에있는 이니셜 라이저의 순서는 관련이 없지만, 자신과 주변의 모든 사람을 제멋대로 유지하기 위해 동일하게하는 것이 좋습니다.

당신은 이것을 가지고 있다고 상상해보십시오 : Foo(int n) : a(n), b(a) { }. 이것은 좋은 것처럼 보이지만 Foo::b이 실제로 Foo::a 전에 선언 된 경우 이는 b의 생성자에 완전한 유형이 필요한 경우 정의되지 않은 동작 일 수 있습니다. 이 문제를 방지하려면 관련 컴파일러 경고를 항상 활성화하고 존중해야합니다.

+2

이것이 UB인지 여부는 'b'의 ctors에 따라 다릅니다. 'B :: B'가 단지'A &'를 취하고 저장한다면, 그것은 잘 정의되어 있습니다. 비슷한 경우'* this'를 멤버 객체에 전달하여 부모를 알고 있습니다. 그것도 생성되기 전에 객체를 "언급"합니다. – MSalters

+0

@MSalters : 감사합니다. 좋은 지적입니다! 편집 됨. –

관련 문제