>  기사  >  백엔드 개발  >  임시 개체에서 개체를 생성할 때 C 11 이동 생성자가 호출되지 않는 이유는 무엇입니까?

임시 개체에서 개체를 생성할 때 C 11 이동 생성자가 호출되지 않는 이유는 무엇입니까?

Patricia Arquette
Patricia Arquette원래의
2024-11-04 19:17:02216검색

Why isn't the C  11 Move Constructor Called When Creating an Object from a Temporary Object?

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

특정 시나리오에서는 C 11 이동 생성자가 호출되지 않을 수 있습니다. 대신 기본 생성자. 이유를 이해하기 위해 예를 살펴보겠습니다.

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

<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>

이 클래스를 사용하면 다음과 같이 객체를 생성할 수 있습니다.

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

    return 0;
}</code>

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

ctor
test
copy
test
ctor  <-- Why not move?
test

그러나 이동 생성자는 마지막 줄에서 호출되지 않습니다. 대신 기본 생성자가 사용됩니다. 이를 설명하려면 복사 제거를 이해해야 합니다.

복사 제거는 특정 조건에서 C 11 표준에서 허용하는 최적화 기술입니다. 이를 통해 컴파일러는 복사/이동 생성자 및 소멸자 오버헤드를 피하면서 임시 객체를 대상 객체에 직접 생성할 수 있습니다.

이 예에서는 임시 "테스트"에서 생성된 X 객체가 z에서 생략됩니다. 이는 복사/이동 생성자가 호출되지 않고 대신 객체가 z로 직접 생성된다는 것을 의미합니다.

다음 조건이 모두 충족되면 컴파일러는 복사 제거를 수행할 수 있습니다.

  • 객체는 참조에 바인딩되지 않은 임시 객체입니다.
  • 객체는 동일한 cv-unqualified 유형의 객체로 복사/이동됩니다.

우리 경우에는 이러한 조건이 만족되므로 복사 제거가 발생하여 이동 생성자 대신 기본 생성자가 사용됩니다. 이동 생성자를 명시적으로 호출하려면 다음과 같이 std::move를 사용할 수 있습니다.

<code class="cpp">X z( std::move(X("test")) );</code>

위 내용은 임시 개체에서 개체를 생성할 때 C 11 이동 생성자가 호출되지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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