2014-01-31 3 views
4

다음 코드에서 리터럴을 사용하여 참조 변수를 초기화합니다.리터럴로 참조 멤버 변수 초기화

class ABC 
{ 
    public: 
    const int& a; 
    ABC():a(43) { } 
    void newfoo() 
    { 
      printf("NEWFOO %d",a); 
    } 
}; 
int main() 
{ 
    ABC obj; 
    obj.newfoo(); 
} 

이 프로그램의 출력은 나는 다음과 같은 코드가 잘 작동하는지 알고 비논리적 보인다 NEWFOO 32767입니다.

int main() 
{ 
    const int& b=3; 
    printf("%d",b); 
} 

여기 무슨 일입니까? 컴파일러가 참조 변수의 초기화 중 일부 임시 변수를 선언하면 클래스가 전역 범위에 있기 때문에 main 변수의 범위가 아닌가?

+0

멤버 참조를 리터럴로 초기화하지 마십시오. 나는 그것이 정의되지 않은 행동이라고 믿는다. –

+1

왜 이렇게 표준화 되었습니까? 이것을 컴파일하게하는 것은 의미가 없습니다. –

답변

2

clang 심지어 어떤 플래그 (see it live)없이이 코드에 대한 다음과 같은 경고를 생성합니다 반면에

warning: binding reference member 'a' to a temporary value [-Wdangling-field] 
ABC():a(43) { } 
     ^~ 

gcc-Wall 또는 -Wextra 중 하나가 필요합니다.

은 우리가 this reference initialization reference 체크 아웃 경우는 말한다 :

생성자 초기화 목록에서 기준 부재에 임시 바운드는 생성자가 종료 될 때까지 오브젝트가 존재하지만큼 지속됩니다.

표준 섹션 ++ 초안 C에서 찾을 수 있습니다 12.2 임시 객체 다음 총알

포함 단락 - 참조 회원에게 임시 바운드 생성자의 ctor에-초기화에를 (12.6.2)는 생성자가 종료 할 때까지 유지됩니다.

2

임시가 만들어지고 참조가 임시로 바인딩됩니다 (C++ 03 8.5.3.5). 일시는 생성자 호출이 끝날 때 파괴되어 매달린 참조를 남깁니다. C++ 03 12.2.5 :

생성자의 ctor-initializer (12.6.2)의 참조 멤버에 대한 임시 바인딩은 생성자가 종료 될 때까지 유지됩니다.