2012-01-26 4 views
0

here이 질문은 Q &에서 발생

난 내가 링크 편집 한 수 있다면 질수도 반드시 거기 후속 의견 요청, 그리고 할 생각 몇 가지 의심이 내 질문에 대한 질문 ... 따라서 새로운 질문.

첫째, 연결된 질문에서 배운 점은 로컬로 돌아 오는 참조가 사악하다는 것입니다.

지금, 그 질문에서 같은 예를 살펴 조금하지만 수정 :

#include<iostream> 
#include<stdio.h> 
#include<string> 
using namespace std; 
class A 
{ 
    public: 
     int x; 
     string s; 
     A(int xx,string ss):x(xx),s(ss) 
    { 
     cout<<"A::A()"<<x<<","<<s<<"\n"; 
    } 
     A(const A& that) 
     { 
      cout<<"cpy ctr\n"; 
      x=that.x; 
      s=that.s; 
     } 
     A& operator=(const A& that) 
     { 
      cout<<"operator=\n"; 
     } 
     ~A() 
     { 
      cout<<"~A()"<<s<<"\n"; 
     } 
}; 

const A& getA1() 
{ 
    A a(1,"A1"); 
    cout<<"returning from A1\n"; 
    return a; 
} 

A& getA2() 
{ 
    A a(2,"A2"); 
    cout<<"returning from A2\n"; 
    return a; 
} 

A getA3() 
{ 
    A a(3,"A3"); 
    cout<<"returning from A3\n"; 
    return a; 
} 

int main() 
{ 
    A &newA2 = getA2();  //.....................LINE 2 
    cout<<"returned from A2\n"; 
    cout<<"-----------------------------\n"; 
    A newA3 = getA3();  //......................LINE 3 
    //A const newConstA3 = getA3(); 
    cout<<"returned from A3\n"; 
    cout<<"-----------------------------\n"; 
    //cout<<"newA2="<<newA2.x<<","<<newA2.s<<"\n"; 
    cout<<"newA3="<<newA3.x<<","<<newA3.s<<"\n"; 

} 

출력은 다음과 같다 ..

A::A()2,A2 
returning from A2 
~A()A2 
returned from A2 
----------------------------- 
A::A()3,A3 
returning from A3 
returned from A3 
----------------------------- 
newA3=3,A3 
~A()A3 

이제 내 의심 ...

  1. 라인 2, fun getA2() (ref로 반환)은 일시적으로 파괴 된 후에 반환되므로 수신 객체 newA2은 위험합니다. (이유는 내가 사용하지 않았기 때문입니다.) 그렇다면 왜 재미를 느낍니까 getA3() 임시로 소멸시킵니다. 그것은 "copy"에 의해 반환되지만 (getA3() 내부의 임시 소멸자는 main()의 끝에서 죽을 때만 개체의 소멸자가 호출됩니다.) 나는 그 임시 직원이 어디 있는지 전혀 모른다. ??

  2. 이제 LINE 2 내가 (결국 지시 대상이 사망했다으로 세그먼트 폴트를 제공합니다)하지만 나던 왜 복사 클릭률이 라인에서 호출되는 여기 A newA2 = getA2();, 복사 클릭률 (CTR)이 호출됩니다에 A& newA2 = getA2();에서 그것을 변경하는 경우 3? 임시 상태가 객체 으로 복사되는 방법은 operator=() 중 하나를 호출 중임을 알 수 있습니까?

  3. 마지막으로 출력은 gcc이지만 MSVC++ 2008에서는 다르게 작동합니까 ?? 코드 A newA3 = getA3();LINE 3과 동일하게 동작합니다. LINE 2과 동일하게 동작합니다. 즉, 복귀하기 전에 temp를 파괴합니다! 모든 단서?

+0

출력 레이아웃과 질문을 따르기가 매우 어렵습니다. 당신은 단순하게 할 수 없습니까? 그리고, 질문마다 하나의 질문을하십시오 ... –

답변

2
  1. 그것은 당신이 Return Value Optimisation에서 혜택을 받고 나타납니다.

  2. 잘못된 개체 임에도 불구하고 참조를 새 개체로 복사하기 때문에.

  3. MSVC와 GCC는 광범위하게 동일하게 작동합니다. 정의되지 않은 동작을 피하십시오 (이것은 보일 수도 있습니다). 그리고 동일한 방법으로 작동하지 않으면 컴파일러에 버그가 있습니다.

+0

so.i gcc가 vC++보다 우세하다고 생각하십니까? – ashishsony

+0

@ashishsony : TBH post VC6 MSVC는 꽤 C++ 표준을 준수합니다. 나는 GCC에 있기 전에 VS 2010에서 람다와 "nullptr"과 같은 것들을 사용할 수 있다고 믿습니다. – Goz

+0

@Goz : 2010 년 이래 C++ 11 : P가되어 _non-compliant_가되었습니다. –

0
  1. 음은 물론 반환되는 값이 파괴되지, 그렇지 않으면 함수에서 아무것도 반환 할 수 없을 것입니다. 로컬 범위에서 복사 한 후 바로 호출 범위의 스택으로 이동한다고 생각합니다.

  2. 복사. 복사가 과도 할 때 (컴파일러는 여기에있는 것처럼), 컴파일러는 일종의 표준 - 규정 "최적화"로서 (부작용이 있더라도) 그것을 제거 할 수 있습니다. 이것에 대한 많은 질문에 문서화되어 있습니다.

  3. 당신이 묻는 것이 명확하지 않습니다. 비교할 출력물 두 개를 표시하지 않았습니다.

+1

-1 그것은 틀렸기 때문에, 특히 1입니다. 지역 변수는 범위 끝에서 존재를 멈추고 파괴됩니다. 값이 복사되기 때문에 함수로부터 값을 반환 할 수 있습니다 (물론 파괴되기 전에). 복사 elision은 완전히 다른 문제입니다 (컴파일러는이 최적화가 허용되지만 의미론에 대한 논쟁을 형성하지 않는 * 최적화 * 만 해당) .- 도대체 누가 이것을 반대 했습니까? –

+0

@Konrad : 어, 뭐라구? 1) 반환되는 값은 로컬 변수가 아닙니다. 그것은 사본입니다. 나는 결코 다르게 말하지 않았다. 꽤 _obviously_, 반환되는 값은 로컬 범위로 파괴 될 수 없습니다 ... 2) 맞습니다. 그렇다고 프로그램의 출력에 영향을 미치지 않는다는 의미는 아닙니다. 이 답변에 대한 문제를 명확히 할 수 있습니까? –

관련 문제