2012-04-13 6 views
4

다른 스레드에서 묻는 a question의 질문에 새로운 질문이 생겼습니다. 그 대답은 분명하지 않습니다.변수의 수명과 수명

그래서 임시 참조를 가지고 있다면 적어도 임시 참조의 수명은 const 참조와 같다고 말하는 C++ 규칙이있는 것으로 보입니다. 하지만 다른 객체의 멤버 변수에 대한 로컬 const 참조가있는 경우와 범위를 벗어날 경우 어떻게 될까요?이 변수의 소멸자를 호출합니까? 그래서 여기

은 원래의 질문에서 프로그램을 수정 :이 코드를 실행하면

#include <iostream> 
#include <string> 
using namespace std; 

class A { 
public: 
    A(std::string l) { k = l; }; 
    std::string get() const { return k; }; 
    std::string k; 
}; 

class B { 
public: 
    B(A a) : a(a) {} 
    void b() { cout << a.get(); } //Has a member function 
    A a; 
}; 

void f(const A& a) 
{ //Gets a reference to the member function creates a const reference 
    stores it and goes out of scope 
const A& temp = a; 
cout << "Within f(): " << temp.k << "\n"; 
} 

int main() { 
    B b(A("hey")); 

    cout << "Before f(): " << b.a<< "\n"; 

    f(b.a); 

    cout << "After f(): " << b.a.k << "\n"; 

    return 0; 
} 

그래서, 내가 "안녕"값 매번 같은 수. 어느 지역의 const 레퍼런스가 구성원 개체에 전달 된 삶을 통해 스스로 바인딩되지 않는다는 것을 암시하는 것처럼 보입니다. 왜 안 그래?

+0

그래서'temp '가 범위를 벗어날 때'b.a'의 소멸자가 호출되기를 기대합니까? 그래서 b는 파괴 된 회원을 포함 할 것인가? – Henrik

+0

당신은 무엇을 기대합니까? 나는 b.a가 바뀔 이유가 보이지 않습니다. – Cosyn

+0

http://stackoverflow.com/questions/3097593/what-happens-when-c-reference-leaves-its-scope – EdChum

답변

10

b.a은 일시적인 것이 아니므로 그 수명은 이후 바인딩되는 참조의 영향을받지 않습니다.

+0

컴파일러가 임시가 아닌 어떻게 추적합니까? 스택이나 힙에 데이터가 저장되는 위치를 알고 있습니까? 해당 메모리 위치에 연결된 여러 참조가 있음을 어떻게 알 수 있습니까? 나는 많은 질문을하고 있지만 C++과 그 컴파일러에 익숙하지 않으므로 나의 호기심을 용서해주십시오. – nndhawan

+0

@nndhawan : 컴파일은 표현식'b.a'를 봅니다. 그것은 기존 객체를 참조하며 _lvalue_입니다. 이것은 컴파일시 결정됩니다. 객체가 런타임에 실제로 저장되는 위치는 중요하지 않습니다. –

+0

여기에는 약간의 기본적인 혼란이있는 것 같습니다 (아마도 표준 자체가 잘못 표현 되었기 때문일 것입니다). 임시의 수명이 연장되는 유일한 시간은 임시 자체가 참조를 초기화하는 데 사용되는 경우입니다. 어느 시점에서 컴파일러는 임시 및 참조를 모두 볼 수 있으므로 수행 할 작업을 알고 있습니다. 다른 레퍼런스에서 레퍼런스를 초기화하는 것은 소스 레퍼런스에 바인딩 된 임시의 수명을 연장시키지 않는다. –

2

나는 당신이 무엇을 요구하고 있는지 잘 모르겠습니다. 코드에서 임시로 볼 수있는 은 bmain으로 초기화하는 표현식에 A("hey")입니다. 그리고 복사 생성자를 사용하여 b.aB::B에 복사됩니다. 그 후에는 더 이상 임시 직원이 없습니다.

보다 일반적으로 임시로 참조 번호 에 바인딩된다는 사실은 반드시 그 수명을 변경하지는 않습니다. 평생을 연장하는 것은 임시가 참조를 초기화하는 데 사용된다는 사실입니다. 의 경우 (예 : temp, f)는 임시 (임시로 초기화되지 않았기 때문에 수명에 영향을주지 않습니다) , 을 참조하십시오. 그리고이 규칙에 예외가 있습니다 : 당신이 초기화 클래스의 의 구성원 참조를 초기화하는 임시을 사용 경우, 그렇게, 수명이 여전히 생성자의 끝을지나 확장되지 않습니다이다 :

class A 
{ 
    std::string const& rString; 
public: 
    A() : rString(std::string("hey")) {} 
    std::string get() const { retur rString; } 
}; 

작동 안 할 것이다.

+0

좋아, 나는 일반적으로 모두가 말하고있는 것을 본다.그러나 나는이 예제가 효과가없는 이유를 알지 못한다. 그것은 intially 카운터, 어떻게 rString을 초기화 하시겠습니까? – nndhawan

+0

@nndhawan 임시로 있지 않습니다. 클래스에 참조가 있으면이 참조는 클래스 외부에서 가져온 것을 참조해야합니다. 생성자가 참조로 참조를 가져옵니다 (그리고 수명 문제는 클라이언트의 책임이므로이를 문서화하십시오) , 또는 다른 곳 (예 : 구성 데이터)에서 조회 한 내용. 그러나 실제로는 구성원으로 참조하는 것은 매우 드뭅니다. 일반적인 해결책은 모든 구성원이 참조가 아닌 값이어야한다는 것입니다. –