2012-08-13 3 views
2

[abc e = a + b]가 호출되면 복사 생성자가 호출되지 않습니다.다음과 같은 경우 오버로드 된 + 및 = 연산자가 값별로 반환되는 경우 복사 생성자가 호출되지 않습니다.

class abc{ 
     int i; 
     public: 
     abc() 
      { 
      i = 10; 
      cout<<"constructor"<<endl; 
     } 
     abc(const abc &a) 
     { 
      cout<<"copy constructor"<<endl; 
      i = a.i; 
     } 
     abc operator=(const abc &a) 
     { 
      cout<<"operator="<<endl; 
      abc temp; 
      temp.i = a.i; 
      return temp; 
     } 
     abc operator+(abc& a) 
     { 
      cout <<"Operator+ called"<<endl; 
      abc temp; 
      temp.i = i+a.i; 
      return temp ; 
     } 
    }; 

    int main() 
    { 
     abc a,b; 
     cout <<"----------------------------------------------"<<endl; 
     a = b; 
     cout <<"----------------------------------------------"<<endl; 
     abc c = a; 
     cout <<"-----------------------------------------------"<<endl; 
     abc d(a); 
     cout <<"-------------------------------------------"<<endl; 
     **abc e = a+b;** 
    } 

는 그러나 방법은 클래스 ABC의 객체에 대한 참조를 반환 다음과 같은 방법으로 대체됩니다 과부하 사업자, 생성자를 복사 할 경우 호출됩니다.

abc& operator=(const abc &a) 
    { 
     cout<<"operator="<<endl; 
     i = a.i; 
     return *this; 
    } 
    abc& operator+(const abc& a) 
    { 
     cout <<"Operator+ called"<<endl; 
     i = i+a.i; 
     return *this ; 
    } 

왜 이런 일이 발생하는지 설명해주세요.

+2

가능한 복제본 [반환 값 최적화 (RVO) 버그가 아닙니까?] (http://stackoverflow.com/questions/3905869/isnt-return-value-optimization-rvo-a-bug) – iammilind

+0

빈약 한 클래스 이름. 변수 이름이'a''b''와'c' 일 때'MyClass','TestClass' 또는 다른 이름으로 호출 할 수 있지만'abc'로 호출 할 수는 없습니다. – abcdabcd987

답변

1

이것은 return value optimization으로 인해 발생합니다.

생성자가 참조를 반환하면 값 비싼 메모리 복사 작업이 수행되지 않으므로이 경우 최적화가 수행되지 않았으므로 예상대로 작동합니다. 값을 반환하면 최적화가 시작되고 예상치 못한 방식으로 작동하지만 표준에 의해 허용됩니다.

+0

나는 당신이 "복사 작업의 제거"에 대해 이야기하고 있다고 가정합니다. 나는 그것이 가치 사례에 의한 반환에 사용 되었기 때문에 놀랐다. 그러나 참조 사례에 의한 반환에는 사용되지 않았다. 같은 것을 명확히 해 주셔서 감사합니다. – Abhijeet

0

표준에 의해 명시 적으로 허용되는 최적화입니다.

n3376
12.8 단락 31

특정 조건을 충족하는

, 일 구현은, 클래스 객체의 복사/이동 구성을 생략 할 수있는 경우에도 복사/이동 선정 생성자 조작 및/또는 객체의 소멸자는 부작용이 있습니다.

이 최적화는 RVO (이 경우)과 특정 조건에서 NRVO을 통해 이루어질 수 있습니다.

0

컴파일러에서 최적화 옵션을 비활성화 할 수 있습니다. 코드를 컴파일하는 동안 사용 된 최적화 플래그를 확인하십시오.