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로 직접 생성된다는 것을 의미합니다.
다음 조건이 모두 충족되면 컴파일러는 복사 제거를 수행할 수 있습니다.
우리 경우에는 이러한 조건이 만족되므로 복사 제거가 발생하여 이동 생성자 대신 기본 생성자가 사용됩니다. 이동 생성자를 명시적으로 호출하려면 다음과 같이 std::move를 사용할 수 있습니다.
<code class="cpp">X z( std::move(X("test")) );</code>
위 내용은 임시 개체에서 개체를 생성할 때 C 11 이동 생성자가 호출되지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!