2014-12-11 8 views
2

는 다음과 같은 코드를 생각해임시 반환 객체를 참조에 할당 할 때 공용 복사 생성자가 필요한 이유는 무엇입니까?

class MyClass 
{ 
    MyClass() 
    { 
     x = 0; 
    } 
    MyClass(const MyClass&) 
    { 
     x = 1; 
    } 
public: 
    int x; 
    MyClass(MyClass&&) 
    { 
     x = 2; 
    } 
    static const MyClass f() 
    { 
     return MyClass(); 
    } 
}; 

int main() 
{ 
    const MyClass& p = MyClass::f(); 
    return 0; 
} 

이 코드는 VC에서 컴파일하지 않습니다 ++ 2010

error C2248: 'MyClass::MyClass: cannot access private member declared in class 'MyClass' 

나는 그것이 망막 정맥 폐쇄와 함께 할 수있는 뭔가가 생각하지만, 내가 더 무엇을 이해하고 싶습니다 그것은하고있다. 복사 생성자를 호출해야하는 이유는 없습니다. 여기

내가 기대하는 내용은 다음과 같습니다

  • 입력 F()
  • 전화 기본 생성자 객체를 반환
  • 통화 이동 생성자
  • 지정 일시 반환 객체 (아마도 RVO에 의해 최적화) 참조 p에

실제로 복사 생성자를 public으로 만들면 컴파일되고 정확하게 작동합니다. 그런 식으로. 복사 생성자는 절대로 호출되지 않습니다. x의 최종 값은 0입니다.

+0

'main'에있는 예제에서는 복사 생성자를 호출하지 않고 대신 ['copy assignment operator'] (http://en.cppreference.com/w/cpp/language/)를 사용합니다. as_operator) – CoryKramer

+3

@Cyber ​​: 아니오, 초기화 작업이며'= '포함 여부에 관계없이 생성자를 사용합니다. –

답변

4

이것은 C++ 03 규칙과 관련이 있습니다. C++ 03에서는 처음에 임시로 참조에 을 할당하면 임시 파일을 복사 할 수 있습니다.

C++ 11부터는이 동작이 사라지고 더 이상 복사가 수행되지 않습니다.

+0

아, 그때 나는 지나치게 빠져 버렸습니다. MSVC++ 2010에는 C++ 11의 일부 기능 (특히 rvalue refs)이 있지만 C++ 03을 기반으로 합니다만 그렇지 않습니까? – Veggie

+0

당신은 그것을 _may_ 복사한다고. 어떤 조건에서? 컴파일러가 아니면 다른 조건이 있습니까? – Veggie

+1

저는 그것이 어떤 기준에 "기반을 두 었는지"정확히 무엇을 의미하는지 모르겠습니다. 이전 버전의 MSVC++는 C++ 11이 출시되기 오래 전에 존재했기 때문에 C++ 11에 대한 코드를 다시 작성하지 않았을 것이라고 나는 생각합니다. "기반"이라는 단어의 의미에서 그렇습니다. C++ 03에서 "기반"입니다. –