2017-03-07 3 views
1

함수가 멤버에 대한 참조를 반환하는 다음 코드를 작성했습니다. 반환 값은 함수에 대한 두 가지 다른 호출 중에 두 가지 방법으로 저장됩니다.함수에서 참조를 반환하면 'auto'가 사용될 때 새로운 임시 객체가 생성됩니까?

  1. 반환 값을 저장하는 데 자동 참조가 사용됩니다. 필자가 가정했듯이 참조가 반환되는 객체의 주소와 반환 값을 저장하는 자동 참조의 주소는 출력에서와 같이 동일합니다.
  2. 'auto'가 반환 값을 저장하는 데 사용됩니다. 나는 auto 변수가 함수에 의해 참조가 반환 된 객체의 값의 복사본을 포함하는 스택에 생성 된 새로운 객체를 생성해야한다고 가정했다. 자동 개체와 실제 개체의 주소가 실제로 다르다는 것을 알 수있었습니다. 그러나, 나는 자동차를 사용하여 생성 된 객체를 호출하는 생성자를 보지 못했습니다. 사실이 경우에 객체가 생성 되었습니까?

// 코드

#include <iostream> 
    using namespace std; 

    class c1 { 
    private: 
     int i; 

    public: 
     c1() { 
      cout << "c1()" << endl; 
      i = 10; 
     } 

    }; 

    class c2 { 
    private: 
     c1 mc1; 

    public: 
     c2() { 
      cout << "c2()" << endl; 
     } 

     c1& getmc1() { 
      cout << "address of mc1 : " << &mc1 << endl; 
      return mc1; 
     } 
    }; 

    int main() { 
     c2 c; 
     auto& c1_1 = c.getmc1(); 
     cout << "address of c1_1 : " << &c1_1 << endl; 

     c2 c_2; 
     auto c1_2 = c_2.getmc1(); 
     cout << "address of c1_1 : " << &c1_1 << endl; 

     return 0; 
    } 


//Output 
c1() 
c2() 
address of mc1 : 00AFF82C --> Same as below address, expected 
address of c1_1 : 00AFF82C 
c1() 
c2() 
address of mc1 : 00AFF814 --> Different from below address, expected 
address of c1_1 : 00AFF82C --> why c1() constructor is not invoked ? 

편집

@NathanOliver, @Tali, 복사 constrcutor에 대해 지적

감사합니다. 나는 하나 추가했고, 나는 올바른 결과물을 볼 수 있었다. 저는 C++의 초보자입니다. 나는 컴파일러가 암시적인 복사본 생성자를 생성한다는 사실을 놓쳤다.

아래는 업데이트 된 프로그램입니다.

#include <iostream> 
using namespace std; 

class c1 { 
private: 
    int i; 

public: 
    c1() { 
     cout << "c1()" << endl; 
     i = 10; 
    } 

    c1(c1 &c) { 
     cout << "c1(c1 &c)" << endl; 
     i = c.i; 
    } 

}; 

class c2 { 
private: 
    c1 mc1; 

public: 
    c2() { 
     cout << "c2()" << endl; 
    } 

    c1& getmc1() { 
     cout << "address of mc1 : " << &mc1 << endl; 
     return mc1; 
    } 
}; 

int main() { 
    // your code goes here 
    c2 c; 
    auto& c1_1 = c.getmc1(); 
    cout << "address of c1_1 : " << &c1_1 << endl; 

    c2 c_2; 
    auto c1_2 = c_2.getmc1(); 
    cout << "address of c1_1 : " << &c1_2 << endl; 

    return 0; 
} 

출력 :

c1() 
c2() 
address of mc1 : 010FFE18 
address of c1_1 : 010FFE18 
c1() 
c2() 
address of mc1 : 010FFE00 
c1(c1 &c) 
address of c1_1 : 010FFDF4 
+0

복사 생성자를 잊어 버렸습니다. – NathanOliver

+1

두 번째 경우에 대해'cout << ...'의 중복 점은 무엇입니까? 'c1_2'에 대해 뭔가를 잡은 다음 무시하고'c1_1'의 주소를 다시 출력합니다. – WhozCraig

+0

@ WhozCraig, 지적 해 주셔서 감사합니다. typo의 고전적인 경우입니다 :). 나는 아래의 게시물과 같이 프로그램을 수정했다. 복사본 생성자를 추가하면 문제가 해결되었습니다. – codeseeker

답변

2

예 새 개체가 구성되어 있지만 c1::c1()를 사용하지. 이러한 복사본은 복사 생성자 c1::c1(const c1 &)을 사용하여 수행됩니다.

예에서 컴파일러가 암시 적으로 생성하도록 복사 생성자를 제공하지 않습니다.