2012-06-29 3 views
1

가능한 중복 :복사 생성자가 호출하지 않은 이유는 무엇입니까?

#include <iostream> 
#include <new> 

using namespace std; 

class test { 
    int *p; 
public: 
    test operator=(test a); 
    test() { 
     p = new int [2]; 
     cout <<"Default Constructor was done here." << "\n"; 
    } 

    test(const test &a) { 
     p = new int [2]; 
     this->p[0] = a.p[0]; 
     this->p[1] = a.p[1]; 
     cout << "Copy Constructor was done here." << "\n"; 
    } 

    ~test() { 
     delete p; 
     cout << "Destructor was done here." << "\n"; 
    } 
    int set (int a, int b) { 
     p[0] = a; 
     p[1] = b; 
     return 1; 
    } 

    int show() { 
     cout << p[0] << " " << p[1] << "\n"; 
     return 2; 
    } 
};  

test test::operator=(test a) { 
    p[0] = a.p[0]; 
    p[1] = a.p[1]; 
    cout << "Operator = was done here" << "\n"; 
    return *this; 
} 

test f(test x) { 
    x.set(100, 100); 
    return x; 
} 

int main() { 
    test first; 
    test second; 
    first.set(12, 12); 

    //f(first); 
    //second = first; 
    second = f(first); 


    first.show(); 
    second.show(); 

    getchar(); 
    return 0; 
} 

복사 생성자 만 세 번을 불렀다 :
Why copy constructor is not called in this case?

내가 코드를 다음습니까? 왜? 우리가 이해한다면, 우리는 4 개의 복사본을 만들었습니다 (func에 객체 보내기, func는 값을 반환, operator =는 operator =에 값을 반환).

+6

많은 양의 복제물을 복사하십시오. –

답변

3

이것은 copy elision의 효과 일 수 있습니다. 컴파일러는 프로그램에 영향을 미치지 않는 곳에서도 객체 복사를 피할 수 있습니다. 복사 생성자/소멸자의 부작용은이 계산기의 프로그램에 영향을 미치지 않습니다. 일반적으로, 임시 매개 변수는 이후에 파괴 될 것이기 때문에 함수 매개 변수로 사용하기 위해 임시를 복사하는 것을 피할 것입니다.

이 표준에 §12.8.32에서 찾을 수 있습니다

특정 조건이 충족

, 구현에도 복사가있는 경우, 클래스 객체의 복사/이동 건설을 생략 할 수있다/move 객체의 생성자 및/또는 소멸자는 부작용이 있습니다. 그러한 경우에 구현은 생략 된복사/이동 작업의 원본과 대상을 동일한 개체를 참조하는 두 가지 다른 방법으로 취급하며 해당 개체의 삭제는 의 두 번째 객체가 최적화없이 파괴되었습니다. return 문에

  • 을 클래스 반환 값의 형태와 기능의에서 : 사본이 생략/ 작업을 이동 전화 copyelision는 (아마도 여러 복사본을 제거하기 위해 결합하는) 다음 상황에서 허용된다 식은
    복사/이동 동작 함수의 리턴 값
  • 직접 자동
    객체를 구성함으로써 생략 될 수
    함수 반환형 같은 CV-unquali 인터넷 혼성 유형의 비 휘발성 자동 오브젝트의 이름
  • 에서 throw-exp 레지스턴스가 피연산자의 범위가 을 초과하지 않는 비 휘발성 자동 객체의 이름 인 경우, 피연산자에서 예외로의 복사/이동 작업 인 (있는 경우)을 포함합니다. 오브젝트 (151) 가 직접 예외 객체 참조 (12.2)에 결합되지 않은 임시 클래스 객체 becopied 것이다
  • 를 자동으로 물체를 구성함으로써 생략 될 수있다/그는 동일한 을 기호와 클래스 객체로 이동 cv-unquali 형식이면 복사/이동 작업을 생략 할 수 임시 대상을 직접 대상으로 구성
    생략 복사/이동
  • 예외 처리기 (15 절)의 예외 선언이 동일한 유형의 객체 (cv-qualification)를 제외하고
    예외 객체 (15.프로그램의 의미
    선언 오브젝트 생성자와 소멸자의 실행 제외 변경 될 경우 1), 복사/이동 연산 예외
    오브젝트 별칭
    bytreatingthe 예외 선언을 생략 할 수있다 예외 선언. 이 경우는 일시적이므로 어쨌든 바로 이후에 파괴 될 것이기 때문에 그 가능성이 단순히 operator=에 대한 입력으로 f에 의해 반환 된 객체를 사용에서

.

+0

출력이 관찰 가능하지 않은 동작입니까? – BoBTFish

+3

컴파일러는 부작용이 있어도 사본을 삭제할 수 있습니다. – jrok

+2

@BoBTF 임은 맞지만 대답이 잘못되었습니다. "컴파일러는 프로그램에 영향을 미치지 않는 곳에서도 오브젝트를 복사하지 않아도됩니다."-이 부분은 올바르지 않습니다. –

관련 문제