2012-02-04 4 views
20

, 왜 내가 잘못 답변을 얻을 않지만 :C++ 생성자 : 어떤이 코드에 문제가 있습니다 쓰레기 const를 참조 초기화가

class X 
{ 
private: 
     const int a; 
     const int& b; 
public: 
     X(): a(10) , b(20) 
     { 
     //  std::cout << "constructor : a " << a << std::endl; 
     //  std::cout << "constructor : b " << b << std::endl; 
     } 

     void display() 
     { 
      std::cout << "display():a:" << a << std::endl; 
      std::cout << "display():b:" << b << std::endl; 

     } 
}; 


int 
main(void) 
{ 
     X x; 
     x.display(); 
return 0; 
} 

위의 코드는 나에게 결과를 줄 것 같은

display():a:10 
display():b:1104441332 

그러나 기본 생성자 내에서 주석이 달린 2 줄을 제거하면 올바른 결과를 얻을 수 있습니다.

constructor : a 10 
constructor : b 20 
display():a:10 
display():b:20 

제발 도와주세요, 고마워요

답변

24

임시에 대한 참조로 초기화됩니다.

20 값이 생성되고 생성자의 범위에만 존재합니다.

이 코드의 동작은 매우 흥미 롭습니다. 내 컴퓨터에서 게시 한 것과 다른 값을 가지지 만 근본적인 동작은 여전히 ​​비 결정적입니다.

참조 지점이 범위를 벗어나면 가비지 메모리를 대신 참조하기 시작하므로 예기치 않은 동작이 발생하기 때문입니다.

Does a const reference prolong the life of a temporary?; 답 특히 C++ 표준의 관련 섹션에 https://stackoverflow.com/a/2784304/383402 링크, 아래의 텍스트 :

A temporary bound to a reference member in a constructor’s ctor-initializer 
(12.6.2) persists until the constructor exits. 

이 항상 거의 생성자 내에서 인쇄에 적합한 값을 얻을, 이유 후 (그러나 가능하게 때로는!) . 생성자가 종료되면 참조 번호 및 모든 베팅이 해제됩니다.

+0

답장을 보내 주셔서 감사합니다. 그 결과를 설명합니다. 하지만 b 초기화하는 방법을 알고 있습니다? –

+1

@VivekBasappa : 의도 한 것처럼 일부 변수를 참조하십시오. 아니면 그냥'a'와 같은 값으로 만드십시오. –

+1

@VivekBasappa 그것은'int'이므로, 아마 그것이 참조가되는 것을 원하지 않을 것입니다. 'int'를 복사하는 것과 같은 코딱지는 비싸다. – Borealid

4

b은 일시적인 것을 말합니다. 기술적으로 범위를 벗어난 임시 20이 읽혀지기 때문에 읽은 시간 (인쇄 할 때)은 읽을 때까지 유효하지 않은 위치입니다.

는 일관성없는 결과를 설명하기 :

그것은 정의되지 않은 동작입니다. 다른 아키텍처에 대한

  • 변화 컴파일러
  • 변화 컴파일러 설정
  • 빌드
  • 변화 클래스 '회원 레이아웃
  • 추가 또는은에서 사물을 제거 다음과 같은 경우에 당신이보고하는 것은 다를 수 있습니다 x
  • 등의 인스턴스 가까운 메모리 영역
,

항상 정의되지 않은 동작을 방지해야합니다.

하지만 왜 값이 변할까요? 참조가 인쇄 될 때까지 재 작성 (예 : 재사용) 된 스택 주소를 참조했을 가능성이 높습니다.

+0

나는 정직하게 "왜 다른가 ..."부분을 이해할 수 없다. 내가 말하는 것에 대해 정확히 지적 해 주시면 고맙겠습니다. "왜"에 대한 첫 번째조차도 ":"다음에 오는 것이 의미가 있지만 그다지 명확하지는 않습니다. – batbrat

+0

@batbrat 확장 – justin

+1

+1 잘 했어! 지금은 훨씬 더 나아졌습니다. – batbrat

3

const&을 생성자에 대한 호출 이후에 살지 않는 임시로 바인딩합니다. C++ 03 표준은 "생성자가 종료 될 때까지 생성자의 ctor-initializer (12.6.2)의 참조 멤버에 임시로 바인딩됩니다"(12.2/5 "임시 객체")라고 명시 적으로 말합니다.

코드에 정의되지 않은 동작이 있습니다. 말도 안되는 소리가 나거나 '작동하는 것'이 나타날 수 있습니다.

FWIW, MSVC 2010

는 그 코드에 다음과 같은 경고 제공 :

C:\temp\test.cpp(12) : warning C4413: 'X::b' : reference member is initialized to a temporary that doesn't persist after the constructor exits 
19

내가 드리겠습니다을 내 컴파일러 대답이 하나

$ g++ -std=c++98 -Wall -Wextra -pedantic test.cpp 
test.cpp: In constructor 'X::X()': 
test.cpp:9:26: warning: a temporary bound to 'X::b' only persists until the constructor exits [-Wextra] 
$ 
당신은 당신의 컴파일러의 경고로 설정해야

잘.

+0

답변 주셔서 감사합니다. b가 왜 임시 초기화인지 설명해 주시겠습니까? 초기화 목록을 통해 const 값을 초기화하려고합니다. –

+1

@VivekBasappa :'X :: b'는 const 참조가 아닌 const 값입니다. –

+1

@VivekBasappa'const'는 문제가 아닙니다. 문제는 참조 할 것이 아무것도없는 * 참조입니다. –