2011-08-25 1 views
8

, 그것은 말한다 :생성자 또는 복사 생성자? 책 <em>일반 프로그래밍과 STL</em> (중국어판)에서

X x = X()는 복사 생성자를 호출합니다.

나에게는 조금 이상합니다. 그리고 나는 이와 같은 테스트 프로그램을 작성한다.

#include <iostream> 

class Test { 

public: 

    Test() { 
     std::cout << "This is ctor\n"; 
    } 

    Test(const Test&) { 
     std::cout << "This is copy-ctor\n"; 
    } 

}; 

int main(int argc, char** argv) 
{ 

    Test t = Test(); 
    return 0; 
} 

결과는 "This is ctor"이다. 좋아, 이제 혼란 스럽네. 맞지?

답변

9

보통 그렇습니다. 임시 구성은 기본 생성되고 복사 생성자가 호출되어 개체 t에 복사됩니다.

[n3290: 8.5/16] : 그 부작용 (콘솔 출력)을 갖더라도

그러나, 실제로 복사가 — 을 최적화 할 수있다 [...] 경우에 따라, 구현은 허용 이 중간 생성 결과를 직접 생성하여 직접 초기화되는 객체에 복사하는 것을 제거하려면 ; 12.2, 12.8 참조.

그리고 (동일한 절에 주어진 예에 관련하여)

[n3290: 12.2/2] [...] 구현 (2)로 전달하기 전에 X를 구성하는 일시적을 사용할 수도 f() X 복사본을 사용하여 생성자; 또는 인수를 보유하는 데 사용 된 공백에 X(2)이 생성 될 수 있습니다. [..]

그러나 복사 생성자 여전히 호출되지 않을 수 있습니다하더라도, 존재해야합니까. 당신은 최적화로 컴파일하는 경우

어쨌든, 당신은 볼 것이다 (아마도 -fno-elide-constructors, GCC와 함께, 또는) 해제 : 이론적으로

This is ctor 
This is copy-ctor 
+2

gcc에서 '-O0'이라도 elision을 막지 못하기 때문에'-fno-elide-constructors'를 사용해야 할 수도 있습니다. –

+0

@Kerrek : 감사합니다! –

+0

* 사소한 *이 아니더라도 복사본을 생략 할 수 있습니다. 로컬 변수 대신 임시를 생성하여 복사본을 생략합니다. 객체 또는 사본의 복잡성은 최적화와 관련이 없습니다. –

4

, X x = X() 임시 객체를 생성하는 기본 생성자를 호출하고, 복사 생성자를 사용하여 x에 복사하십시오.

실제로 컴파일러는 복사 구성 부분을 건너 뛰고 x을 직접 생성 할 수 있습니다 (데이빗이 주석에서 지적한대로 여전히 복사 생성자에 구문 적으로 액세스 할 수 있어야 함). 대부분의 컴파일러는 적어도 최적화가 가능할 때 그렇게합니다.

+4

복사 생성자는 복사가 생략 된 경우에도 사용할 수 있어야합니다. 즉, 액세스 할 수없는 경우 컴파일러는 오류가있는 행을 거부합니다. –

+0

@ David : 네 말이 맞아. 나는 그것을 내 대답에 포함 시켰습니다. 이걸 가져 주셔서 감사합니다. – sbi

2

Return Value Optimisation(RVO) (일명 Copy Elision라고도 함) 형식은 최적화에 많은 도움이 될 수 있습니다. 연결된 위키 피 디아 페이지에는 무슨 일이 일어나고 있는지에 대한 아주 좋은 설명이 있습니다.

+3

나는 그것이 정확하다고는 생각하지 않는다. 여기에 'X'를 반환하는 함수 호출이 없습니다 (생성자가 반환 값을 가지고 있지 않음을 기억하십시오). 이것은 복사 Elision으로, 관련이 있지만 뚜렷한 개념입니다. –

+0

동의합니다. 이것은 엄격하게 RVO가 아니지만 (관련성이 있지만). –

+0

@ 토막 : 이것은 완전히 잘못된 것은 아닙니다. 이것은 * 최적화 *의 종류 * 변형입니다. +1은 상향 회선과 균형을 이룬다. –