문제

함수에서 로컬 변수에 대한 참조를 반환하는 데 몇 가지 질문이 있습니다.

class A {
public:
    A(int xx)
    : x(xx)
    {
        printf("A::A()\n");
    }
};

const A& getA1()
{
    A a(5);
    return a;
}

A& getA2()
{
    A a(5);
    return a;
}

A getA3()
{
    A a(5);
    return a;
}

int main()
{
    const A& newA1 = getA1(); //1
    A& newA2 = getA2(); //2
    A& newA3 = getA3(); //3
}

내 질문은 =>입니다

  1. 구현입니다 getA1() 옳은? 로컬 변수의 주소를 반환하거나 임시로 반환하기 때문에 잘못된 것 같습니다.

  2. 진술 중 어느 것입니다 main (1,2,3) 정의되지 않은 행동으로 이어질 것인가?

  3. ~ 안에 const A& newA1 = getA1(); 표준은 참조가 범위를 벗어날 때까지 Const Reference에 의해 임시 구속이 파괴되지 않을 것을 보장합니까?

도움이 되었습니까?

해결책

1. IS getA1() 구현이 정확합니까? 로컬 변수의 주소를 반환하거나 임시로 반환하기 때문에 부정확하다고 생각합니다.

유일한 버전 getAx() 그것은 당신의 프로그램에서 정확합니다 getA3(). 다른 두 사람 모두 나중에 어떻게 사용하든 정의되지 않은 동작을 가지고 있습니다.

2. 메인 (1,2,3)의 진술 중 어느 것이 정의되지 않은 행동으로 이어질까요?

어떤 의미에서 그들 중 누구도 없습니다. 1과 2의 경우 정의되지 않은 행동은 기능의 신체의 결과입니다. 마지막 줄의 경우 newA3 임시를 비 Const 참조에 바인딩 할 수 없으므로 컴파일 오류 여야합니다.

3.에서 const A& newA1 = getA1(); 표준은 a const 참조가 범위를 벗어날 때까지 참조가 파괴되지 않습니까?

아니요. 다음은 다음의 예입니다.

A const & newConstA3 = getA3 ();

여기, getA3() 임시를 반환하고 해당 임시의 수명이 이제 물체에 묶여 있습니다. newConstA3. 다시 말해서 임시는까지 존재합니다 newConstA3 범위를 벗어납니다.

다른 팁

Q1 : 예, 이것은 문제입니다. Q2에 대한 답변을 참조하십시오.

Q2 : 1 및 2는 Geta1 및 Geta2의 스택에서 로컬 변수를 참조 할 때 정의되지 않습니다. 이러한 변수는 범위를 벗어나지 않으며 더 이상 사용할 수 없으며 스택이 지속적으로 변하면서 더 나빠질 수 있습니다. geta3는 반환 값의 사본이 생성되어 발신자에게 반환되기 때문에 작동합니다.

Q3 : Q2에 대한 답변을 보는 그러한 보증은 없습니다.

주요 문제는 당신이 전혀 시간을 돌려주지 않는다는 것입니다.

return A(5);

보다는

A a(5);
return a;

그렇지 않으면 일시적이 아닌 로컬 변수 주소를 반환합니다. 그리고 임시 to const 참조는 임시에만 적용됩니다.

나는 여기에 설명 된 것 같아요 :Const 참조에 임시

VC6에서 이것을 컴파일하면이 경고를 받게됩니다.

****** 컴파일러 경고 (레벨 1) C4172 로컬 변수 또는 임시 주소의 반환 주소는 로컬 변수 또는 임시 오브젝트의 주소를 반환합니다. 로컬 변수와 임시 객체는 함수가 반환 될 때 파괴되므로 반환 된 주소가 유효하지 않습니다. ******

이 문제를 테스트하는 동안 흥미로운 것을 발견했습니다 (주어진 코드가 VC6에서 작동합니다) :

 class MyClass
{
 public:
 MyClass()
 {
  objID=++cntr;
 }
MyClass& myFunc()
{
    MyClass obj;
    return obj;
}
 int objID;
 static int cntr;
};

int MyClass::cntr;

main()
{
 MyClass tseadf;
 cout<<(tseadf.myFunc()).objID<<endl;

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top