2011-01-18 3 views
7

12.2.5 표준 03 C++의 인용 부분 Happy Mittal 사용자 this question에서 : 생성자가를 종료 할 때까지 생성자의 ctor에-초기화 (12.6.2)에서 기준 부재에 임시 바운드 지속됩니다.C++ Standard의 멤버 수명 문에 임시로 바인딩되는 점은 무엇입니까?

어쨌든 유용 할 수 있습니까? 일단 임시 생성자가 종료되면 생성자가 종료되지만 참조는 바운드 상태로 남아 있습니다. 즉, 이미 파괴 된 객체에 바인드됩니다.

외부 개체의 전체 수명 동안 여전히 매달린 참조가있는 경우 임시 수명을 너무 신중하게 지정해야하는 점은 무엇입니까? 이 시나리오는 어떤 시나리오에서 유용 할 수 있습니까?

+1

나 자신에게 같은 질문을하고있었습니다. 이 문구는 C++ 0x FCD (n3225)의 12.2 [class.temporary] 주 5에서 변경되지 않았습니다. –

답변

7

참조 개체를 죽은 개체에 바인딩하는 것은 유용하지 않지만이 경우에는 참조에 바인딩 된 "일반"임시 수명 연장이 적용되지 않는다는 것이 분명합니다.

또한 ctor 초기화 프로그램에서 특별히 적용되는 임시 수명 연장을 지정합니다. ctor 본문이 실행되기 전에 죽어가는 것이 아니라 ctor의 끝까지 확장됩니다. 이것은 전체 지점이 ctor를 실행하는 "영리한"클래스를 제외하고는 유용하지 않으며 이러한 유형의 (ab) 사용은 올바르게 피할 수 있습니다.

나는 후자의 실제 사례가 없다는 것을 알고 있지만 소멸자가 없으면 평생 동안 "영리한"수업을 받았고 사용법은 어땠는지 깨닫는다. C++ 0x에서 dtors의 기본 의미를 처리하는 방법에 대한 논의에서 이는 실제 사용과 came up을 가졌습니다.

+0

해당 링크의 좋은 자료! +1 – jweyrich

2

D 언어에서는 어느 정도 자유롭게 작성 프로세스를 작성할 수 있습니다. 그러나 C++에서는 구조/초기화 순서가 엄격하게 규정되어 있습니다. 따라서 클래스 초기화에 비용이 많이 드는 계산이 필요한 경우 과 같은 코드를 사용하면 다음과 같은 경우가 꺼리는 경우가 있습니다.

struct S { 
    Args const &r; 
    A a; 
    B b; 
    S(args....) 
    : r(expensive_func(args....)), a(r.for_a), b(r.for_b) {} 
}; 
+1

참조 멤버를 피하고 모든 인스턴스에서 발생할 수있는 오버 헤드를 피하기 위해 리팩토링되었습니다.'struct SDetails {A a; B b; SDetails (args const & r) : a (r.for_a), b (r.for_b) {}}; 구조체 S : private SDetails {S (/ * args ... * /) : SDetails (expensive_func (/ * args ... * /)) {}} ' –

+1

리팩토링은 C++ 0x로는 더 쉽고/:'struct S {A a; B b; S (args const & r) : a (r.for_a), b (r.for_b), S (/ * args ... * /) : S {}};' –

+0

즉, C++ 03에서 초기화가 때때로 임시 해결책을 필요로한다는 것을 인식하지만, 이런 식으로 참조 멤버를 사용하지 않을 것입니다. –

1

컴파일러 작성자에게 유용합니다. 그들은 이미 스코프의 끝에서 묶인 임시 변수를 없애기위한 로직을 가지고 있으며, 생성자의 종료는 그러한 포인트 중 하나입니다. 이 규칙을 사용하면 컴파일러는 해당 시점을 재사용하여 그러한 임시 변수를 제거 할 수 있습니다.

표준은 실제로 평생에 따라 결정되어야하며 다른 유일한 합리적인 포인트는 ctor 초기화 프로그램 목록 다음에 ctor 본문 앞에있는 것입니다. 임시 테이블이 그렇지 않으면 파괴되는 지점이 아니며 함수 범위 try {} catch() 블록 (ctor 초기화 프로그램 목록을 포함)을 방해 할 수 있습니다.

+0

ctor 초기화 프로그램 내의 각 초기화 표현식이 이미 서브 표현식이 아니기 때문에 이미 전체 표현식이 아닙니다. 다른 표현식 (C++ 03, §1.9p12)? 그렇다면 일시적인 오브젝트 파기가이 지점에서 이미 필요합니다. 예를 들면 :'struct A {int foo, bar; '컴파일러 작성자는 (컴파일러를 전체적으로 간단하게) 재사용 할 수있다. "항상 죽은"참조 회원을 허용하는 언어 –

+0

글쎄, 그건 가능했을거야. 그러나 그것이 유용할까요? 나는 그러한 디자인의 위험이 그 이익보다 중요하다고 제안 할 것이다. – MSalters

+0

그 점이 아닌가요? lifetime-extended temporaries에 대한 참조 멤버는 return 문에서 임시 객체에 바인드 된 참조와 같이 완전히 모호한 상태가 아닌 * something *을 지정하는 경우를 제외하고는 현재 지정된대로를 포함하여 * 유용하지 않습니다. –