>백엔드 개발 >C++ >복사 제거가 활성화된 경우 C 11에서 이동 생성자가 호출되지 않는 이유는 무엇입니까?

복사 제거가 활성화된 경우 C 11에서 이동 생성자가 호출되지 않는 이유는 무엇입니까?

DDD
DDD원래의
2024-11-06 09:46:02306검색

Why Is the Move Constructor Not Called in C  11 When Copy Elision Is Enabled?

C 11 이동 생성자가 호출되지 않음, 기본 생성자가 선호됨

C에서 클래스로 작업할 때 이동 생성자가 다음 용도로 활용될 것으로 예상됩니다. 효율적인 자원 이전. 그러나 경우에 따라 기본 생성자가 예기치 않게 대신 선택될 수 있습니다.

문제 설명

다음 클래스를 고려하세요.

<code class="cpp">class X {
public:
    explicit X(char* c) { cout << "ctor" << endl; init(c); }
    X(X& lv)  { cout << "copy" << endl;  init(lv.c_); }
    X(X&& rv) { cout << "move" << endl;  c_ = rv.c_; rv.c_ = nullptr; }

    const char* c() { return c_; }

private:
    void init(char* c) { c_ = new char[strlen(c) + 1]; strcpy(c_, c); }
    char* c_;
};</code>

With 샘플 사용법:

<code class="cpp">X x("test");
cout << x.c() << endl;
X y(x);
cout << y.c() << endl;
X z(X("test"));
cout << z.c() << endl;</code>

예상 출력은 다음과 같습니다.

ctor
test
copy
test
ctor move test

그러나 마지막 줄은 예기치 않게 "move" 대신 "ctor"를 출력합니다.

설명

C 11 표준에 따르면 특정 상황에서는 이동 생성자를 호출해야 합니다. 이 경우 X("test")로 z를 구성할 때 이동이 발생해야 합니다. 그러나 기본 생성자가 대신 호출됩니다.

이 동작은 컴파일러가 복사 또는 이동 작업을 수행하지 않고 대상에 임시를 직접 생성할 수 있도록 하는 최적화 기술인 복사 제거로 인해 발생합니다. 이 최적화는 컴파일러가 복사/이동 작업이 불필요하고 제거될 수 있다고 판단하는 경우에 적용됩니다.

주어진 시나리오에서 컴파일러는 임시 X("테스트")를 복사 제거 후보로 간주합니다. 동일한 표현식 내에서 자동으로 생성되고 소멸되기 때문입니다. 결과적으로 이동 작업을 생략하고 임시 데이터를 사용하여 z를 직접 구성하므로 기본 생성자가 호출됩니다.

결론

복사 제거로 인해 예상치 못한 결과가 발생할 수 있습니다. 이동 생성자를 사용하여 작업할 때의 동작입니다. 예상되는 상황에서 이동 생성자가 호출되는 것을 방지할 수 있기 때문입니다. 컴파일러는 최적화 경험적 방법을 기반으로 복사 제거를 적용할 수 있으며, 이는 컴파일러와 최적화 설정에 따라 다를 수 있습니다. 복사 제거와 이것이 프로그램 동작에 미치는 잠재적인 영향을 인식하는 것이 중요합니다.

위 내용은 복사 제거가 활성화된 경우 C 11에서 이동 생성자가 호출되지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.