2013-05-02 1 views
2

(최소 버전) : 최신는 MinGW g를 사용하는 경우C++ - 파생 된 참조를 통해 호출되는 기본 구현? 다음 코드를 고려

#include <iostream> 

struct Base 
{ 
    virtual ~Base() {} 

    virtual void test() const { std::cout << "base"; } 
}; 

struct Derived : public Base 
{ 
    void test() const { std::cout << "derived"; } 
}; 

struct Composite 
{ 
    const Derived &ref; 

    Composite(const Derived &ref) : ref(ref) {} 

    void testRef() const { ref.test(); } 
}; 

int main() 
{ 
    Composite c((Derived())); 
    c.testRef(); 
} 

이 사실은 '기본'을 생산 ++! 그게 컴파일러 버그인가요, 아니면 제가 빠진 것이 있습니까? 누군가 VS에서 이것을 테스트 할 수 있습니까?

저는 다형성, 스택 기반 레퍼런스, 임시 객체 (C++ 표준 12.2) 등을 사용하여 숙련 된 C++ 프로그래머라고 생각합니다. 따라서 평생 연장을 적용해야한다는 것을 알고 있습니다.

이 동작은 기본 (가상 또는 비보안)에 소멸자를 정의하고 임시 파일을 사용하는 경우에만 발생합니다. 이자형. '파생'사용을 생산하고 다음

int main() 
{ 
    Derived d; 
    Composite c(d); 
    c.testRef(); 
} 
+2

복합기에서 임시 파일이 삭제되었지만 (ref로) 캡처 된 경우 정의되지 않은 동작이 될 수 있습니다. c. –

+2

임시 파일은'c.testRef'를 호출하기 전에 파기됩니다. 코드가 정의되지 않은 동작을 보입니다. 실제로, 그것은 [여기에] 충돌합니다 (http://ideone.com/xGQilt). – mfontanini

+0

@mfontanini : 평생 연장은 어떨까요? 파생 된 결과를 반환하는'const Derived & ref = createDerived();'를 왜 할 수 있습니까? 요청 [여기] (http://stackoverflow.com/questions/4086508/const-reference-for-temporary-lifetime-lengthening). – Philip

답변

5
Composite c((Derived())); 

이 줄은 유형 Derived의 임시 객체가 c의 생성자에 전달 만든 다음 임시 오브젝트를 파괴합니다. 그 후에 모든 배팅은 꺼져 있습니다.

2
Composite c((Derived())); 

Base의 소멸자를 정의하고 프로그램에서 Composite 생성자를 떠나면 파생 및 기본 소멸자가 실행됩니다. base의 소멸자에서 Base의 가상 함수를 호출 할 때 오류를 피하기 위해, 파생 함수가 파생됨에 따라 가상 함수 포인터 (이 테스트 코드의 객체 주소 만)가 파생 된 가상 함수 테이블을 가리 키지 않습니다. 베이스. 소멸자를 정의하지 않으면 아무 것도하지 않습니다. 주소가 여전히 파생 가상 함수 테이블을 가리키고 있습니다.

c.testRef(); 

ref는 여전히 개체의 주소와 가상 함수 테이블의 주소를 가져 와서 테이블의 함수를 호출합니다. 그래서 차이가 있습니다.

VC 8.0에서 테스트하고 메모리를 확인하십시오. 이것은 어떤 종류의 "행운"때문에 발생합니다.

+0

+1을 선택해야합니다. – Philip

관련 문제