21 сСнтября 2021

πŸ›  ΠžΡΠ½ΠΎΠ²Ρ‹ move semantics Π² C++

UE4 C++ Developer. Currently working with Flying Wild Hog on the Space Punks title. Author of articles on C++, GameDev, Unreal Engine and general programming
Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ move semantics, Π·Π°Ρ‡Π΅ΠΌ ΠΈ ΠΊΠΎΠ³Π΄Π° ΠΎΠ½Π° Π½ΡƒΠΆΠ½Π°, ΠΈ ΠΊΠ°ΠΊ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ этого ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π° C++.
πŸ›  ΠžΡΠ½ΠΎΠ²Ρ‹ move semantics Π² C++

Π§Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π·Π½Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄ ΠΏΡ€ΠΎΡ‡Ρ‚Π΅Π½ΠΈΠ΅ΠΌ этой ΡΡ‚Π°Ρ‚ΡŒΠΈ?

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΡŒ Π·Π½Π°ΠΊΠΎΠΌ с ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠ΅ΠΉ ссылок Π² C++, классов, конструкторов, конструкторов копирования, ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² копирования, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΠΌ Ρ‚Ρ€Ρ‘Ρ….

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
Move semantics Π±Ρ‹Π»Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° Π² C++ 11, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΏΡ€ΠΈ использовании слишком старого компилятора данная Ρ„ΠΈΡ‡Π° Π±ΡƒΠ΄Π΅Ρ‚ нСдоступна.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ rvalue ΠΈ lvalue

КаТдоС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² C++ характСризуСтся двумя свойствами: Ρ‚ΠΈΠΏΠΎΠΌ ΠΈ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ΅ΠΉ значСния (value category [1]). Π’ контСкстС Ρ€Π°Π·Π±ΠΎΡ€Π° move semantics нас интСрСсуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послСднСС. ПолноС описаниС ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ – Ρ‚Π΅ΠΌΠ° для ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΌΡ‹ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ свСдСния ΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ.

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ языка опрСдСляСт Ρ‚Ρ€ΠΈ основныС ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈ Π΅Ρ‰Ρ‘ Π΄Π²Π΅ составныС, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ Π½Π° основС ΠΏΠ΅Ρ€Π²Ρ‹Ρ… Ρ‚Ρ€Ρ‘Ρ….

Π‘Π°Π·ΠΎΠ²Ρ‹ΠΌΠΈ катСгориями Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΡΠ²Π»ΡΡŽΡ‚ΡΡ lvalue, prvalue ΠΈ xvalue:

  • lvalue [2] (ΠΎΡ‚ left-hand value – Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ слСва ΠΎΡ‚ Ρ€Π°Π²Π½ΠΎ) – фактичСски всё, Ρ‡Π΅ΠΌΡƒ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ присвоСно Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, пСрСмСнная, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ разымСновывания указатСля, ссылка.
  • prvalue [3] (ΠΎΡ‚ pure rvalue) – Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ нСпосрСдствСнно ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ»ΠΈ описываСт ΠΎΠΏΠ΅Ρ€Π°Π½Π΄, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰ΠΈΠΉΡΡ ссылкой, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ постфиксных ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° ΠΈΠ»ΠΈ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π°, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ арифмСтичСской ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.
  • xvalue [4] (ΠΎΡ‚ expiring value) – ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Π»ΠΈΠ·ΠΊΠΈ ΠΊ ΠΊΠΎΠ½Ρ†Ρƒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ (lifetime [5]). ЀактичСски xvalue – это Π°Π½ΠΎΠ½ΠΈΠΌΠ½Ρ‹Π΅ ссылки Π½Π° rvalue (ΠΎ ссылках Π½Π° rvalue – Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅), Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΡ… ссылки Π½Π° rvalue.

ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ² Ρ‚Ρ€ΠΈ основныС ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π΄Π²Π΅ ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ (составныС) – glvalue ΠΈ rvalue:

  • glvalue [6] (ΠΎΡ‚ generalized lvalue) – Π»ΠΈΠ±ΠΎ lvalue, Π»ΠΈΠ±ΠΎ xvalue.
  • rvalue [7] (ΠΎΡ‚ right-hand value – Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ справа ΠΎΡ‚ Ρ€Π°Π²Π½ΠΎ) – Π»ΠΈΠ±ΠΎ prvalue, Π»ΠΈΠ±ΠΎ xvalue.

Для ясности ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅ΠΌ Π²Π·Π³Π»ΡΠ½ΡƒΡ‚ΡŒ Π½Π° Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΡƒ Π’Π΅Π½Π½Π°:

πŸ›  ΠžΡΠ½ΠΎΠ²Ρ‹ move semantics Π² C++
ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
lvalue Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ всСгда находится слСва ΠΎΡ‚ Π·Π½Π°ΠΊΠ° Ρ€Π°Π²Π½ΠΎ, Π° rvalue – справа ΠΎΡ‚ Π½Π΅Π³ΠΎ. Π’Π°ΠΊ Π±Ρ‹Π»ΠΎ Π΄ΠΎ ввСдСния move semantics Π² C++ 11.

Π”ΠΎ C++ 11 ΠΌΡ‹ ΠΈΠΌΠ΅Π»ΠΈ лишь lvalue ΠΈ rvalue, Π° послС – rvalue Ρ€Π°Π·Π΄Π΅Π»ΠΈΠ»ΠΈ Π½Π° Π΄Π²Π° Π²ΠΈΠ΄Π°: xvalue ΠΈ prvalue, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ ΡΠΎΠ²ΠΎΠΊΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ xvalue ΠΈ lvalue стали Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒ glvalue.

Π“Ρ€ΡƒΠ±ΠΎ говоря, lvalue – всё, Ρ‡Π΅ΠΌΡƒ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ явно присвоСно Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. rvalue – это Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΠ»ΠΈ значСния, Π½Π΅ связанныС Π½ΠΈ с ΠΊΠ°ΠΊΠΈΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ; Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π²ΠΈΡ‚Π°ΡŽΡ‰Π΅Π΅ Π² Π²ΠΎΠ·Π΄ΡƒΡ…Π΅ ΠΈ Π½ΠΈ Π·Π° Ρ‡Π΅ΠΌ Π½Π΅ Π·Π°ΠΊΡ€Π΅ΠΏΠ»Ρ‘Π½Π½ΠΎΠ΅.

Бсылки Π½Π° rvalue

ΠžΡΡ‚Π°Π²ΠΈΠ² самоС слоТноС ΠΏΠΎΠ·Π°Π΄ΠΈ, ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ Π±ΠΎΠ»Π΅Π΅ Π±Π»ΠΈΠ·ΠΊΠΈΡ… ΠΊ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ Π²Π΅Ρ‰Π°Ρ…, ΠΎ ссылках Π½Π° rvalue.

ΠŸΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π° C++ постоянно ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΈ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°ΡŽΡ‚ΡΡ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ Ρ€ΠΎΠ΄Π° Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ (rvalue). Π”ΠΎ C++ 11 ΠΌΡ‹ Π½Π΅ ΠΈΠΌΠ΅Π»ΠΈ возмоТности ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ эти ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ для Π±ΡƒΠ΄ΡƒΡ‰Π΅Π³ΠΎ использования, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΌΠΎΠ³Π»ΠΈ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° Π½ΠΈΡ… (Π²Π΅Ρ€Π½Π΅Π΅, ΠΌΠΎΠ³Π»ΠΈ, Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ константныС ссылки, Π° Π·Π½Π°Ρ‡ΠΈΡ‚, лишаясь возмоТности измСнСния).

Π‘ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΎΠΌ C++ 11 всё измСнилось: появилась Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° rvalue (ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ rvalue Ρ‡Π΅Ρ€Π΅Π· эти ссылки) Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΌΡ‹ Π΄ΠΎ этого ΡΡΡ‹Π»Π°Π»ΠΈΡΡŒ Π½Π° lvalue (кстати говоря, Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² C++ ΠΌΡ‹ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌ просто ссылками, являСтся Π½Π° самом Π΄Π΅Π»Π΅ ссылками Π½Π° lvalue). ВрСмя для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

Листинг 1
        #include <iostream>

//ΠŸΠΎΠ΄ΠΎΠΏΡ‹Ρ‚Π½Ρ‹ΠΉ класс
class X {
public:
    void setA(double a) {
        //Какой-Ρ‚ΠΎ сСттСр
    }
};

X someFunctionReturningX() {
    X x;
    return x;
}

int main() {
    // X& xLvalueRef = someFunctionReturningX(); //НС скомпилируСтся - нСльзя ΠΏΡ€ΠΈΠ²ΡΠ·Π°Ρ‚ΡŒ rvalue ΠΊ ссылкС Π½Π° lvalue
    const X& xConstLvalueRef = someFunctionReturningX();
    //xConstLvalueRef.setA(0); //НС скомпилируСтся
    X&& xRvalueRef = someFunctionReturningX(); //ΠŸΡ€ΠΈΠ²ΡΠ·Ρ‹Π²Π°Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΊ ссылкС Π½Π° rvalue - ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΌΠ΅Π½ΡΡ‚ΡŒ
    xRvalueRef.setA(0);
}

    
  • 1-я строка main, Π±ΡƒΠ΄ΡŒ ΠΎΠ½Π° раскоммСнтирована, Π½Π΅ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π»Π°ΡΡŒ Π±Ρ‹, Ρ‚.ΠΊ. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ ΠΏΡ€ΠΈΠ²ΡΠ·Ρ‹Π²Π°Ρ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ (rvalue) ΠΊ ссылкам Π½Π° lvalue. Однако ΠΎΠ½ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΠΏΡ€ΠΈΠ²ΡΠ·Ρ‹Π²Π°Ρ‚ΡŒ rvalue ΠΊ константным ссылкам Π½Π° lvalue, Ρ‡Ρ‚ΠΎ ΠΈ происходит Π²ΠΎ 2-ΠΉ строкС. Но с константными ссылками Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°: ΠΎΠ½ΠΈ константныС! ΠœΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π½ΠΈΡ‡Π΅Π³ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ с привязанным rvalue, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚Π°ΠΊΡƒΡŽ ссылку, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ 3-я строка.
  • 4-я строка начинаСтся Π½ΠΎΠ²Ρ‹ΠΌ синтаксисом – двумя ампСрсандами (&&), ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰ΠΈΠΌΠΈ объявлСниС ссылки Π½Π° rvalue [8]. Π”Π°Π»Π΅Π΅ ΠΊ этой ссылкС привязываСтся rvalue, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅, ΠΊΠ°ΠΊ Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· 5-ΠΉ строки, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ.
ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
ВрСмя ΠΆΠΈΠ·Π½ΠΈ rvalue, привязанного ΠΊ ссылкС Π½Π° rvalue, Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ΡΡ Π΄ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ этой ссылки.

Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ сама ссылка Π½Π° rvalue являСтся lvalue.

Π­Ρ‚ΠΎ всё ΠΎΡ‡Π΅Π½ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΠΎ, скаТСтС Π²Ρ‹, Π½ΠΎ ΠΊΠ°ΠΊ это ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ ΠΌΠ½Π΅ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹? Об этом – Π½ΠΈΠΆΠ΅.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ move semantics ΠΈ ΠΊΠΎΠ³Π΄Π° ΠΎΠ½Π° ΠΈΠΌΠ΅Π΅Ρ‚ мСсто

Π”ΠΎΠ±Π°Π²ΠΈΠΌ Π² наш класс X конструктор ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, конструктор ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ копирования, Π° Ρ‚Π°ΠΊΠΆΠ΅ объявлСниС указатСля Π½Π° int.

Листинг 2
        X() {
    resource = new int[100];
}

X(const X& x) {
    for (int i = 0; i < 100; ++i)
        resource[i] = x.resource[i];
}

X& operator=(const X& x) {
    X copy(x);
    std::swap(resource, copy.resource);

    return *this;
}

~X() {
    delete[] resource;
}

private:
    int* resource = nullptr;

    

resource здСсь – это ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, тяТСло ΠΈ Π΄ΠΎΠ»Π³ΠΎ ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈ лишнСго копирования ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… стоит ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ.

Π—Π°ΠΌΠ΅Π½ΠΈΠΌ main ΠΈΠ· листинга 1 Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ:

Листинг 3
        int main() {
    X x;
    x = someFunctionReturningX(); //Π’Ρ‹Π·ΠΎΠ² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° копирования, Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ создаётся копия Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
}

    
ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ листинг 3 компилируСтся, ΠΊΠ°ΠΊ C++03, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ move semantics Π΅Ρ‰Ρ‘ Π½Π΅ сущСствовало.

Π—Π°ΠΌΠ΅Ρ‚ΠΈΠ»ΠΈ, Π΄Π°? ΠœΡ‹ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ содСрТимоС Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ копирования фактичСски ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ, просто Π·Π°Π±Ρ€Π°Π² (пСрСмСстив) рСсурс ΠΈΠ· Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Ρ‚.ΠΊ. этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ всё Ρ€Π°Π²Π½ΠΎ ΠΎΡ‡Π΅Π½ΡŒ скоро (послС Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· конструктора копирования) Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ ΠΈ Π½ΠΈΠΊΡ‚ΠΎ Π½Π΅ пострадаСт, Ссли Π΅Π³ΠΎ содСрТимоС станСт пустым (ΠΈΠ»ΠΈ Π½Π΅ пустым, Π½ΠΎ Π½Π΅Π²Π°Π»ΠΈΠ΄Π½Ρ‹ΠΌ). Π­Ρ‚ΠΎ ΠΈ Π΅ΡΡ‚ΡŒ move semantics.

Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ move semantics Π½Π΅ являСтся способом ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строки вашСго ΠΊΠΎΠ΄Π°. Move semantics – это ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹Ρ… случаях. НСсмотря Π½Π° это, ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π΄ΠΎΡ€ΠΎΠ²ΠΎ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΠΎΠ±Ρ‰ΡƒΡŽ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

Π­Ρ‚ΠΎ всё Π·Π²ΡƒΡ‡ΠΈΡ‚ ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π½ΠΎ ΠΊΠ°ΠΊ это Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ? ΠžΡ‡Π΅Π½ΡŒ просто, для этого Π½Π°ΠΌ понадобятся…

ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния

Π‘++ 11 Π΄Π°Π» Π½Π°ΠΌ Π΄Π²Π° инструмСнта для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ move semantics Π² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… классах – конструктор пСрСмСщСния ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния. Π­Ρ‚ΠΎ своСго Ρ€ΠΎΠ΄Π° Π°Π½Π°Π»ΠΎΠ³ΠΈ конструктора ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° копирования, Π½ΠΎ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Π΅ Π½Π΅ для копирования, Π° для пСрСмСщСния. Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΈΡ… Π² наш класс X:

Листинг 4
        X(X&& x) noexcept {
    std::swap(resource, copy.resource);
}

X& operator=(X&& x) noexcept {
    std::swap(resource, copy.resource);

    return *this;
}

    

Π’ конструкторС пСрСмСщСния ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° рСсурс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ, мСняСтся Π½Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° рСсурс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅ΠΌ, ΠΈ Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚. Π’ΠΎ ΠΆΠ΅ самоС происходит Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π΅ пСрСмСщСния. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ тяТСловСсный рСсурс, Π½ΠΎ ΠΏΡ€ΠΈ этом Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ копирования Π½Π΅ происходит!

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈ использовании компилятора, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰Π΅Π³ΠΎ C++ 11, ΠΊΠΎΠ΄ ΠΈΠ· листинга 3 большС Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ копирования, Π° вмСсто Π½Π΅Π³ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния. ΠŸΠΎΡ‡Π΅ΠΌΡƒ? ΠŸΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС справа ΠΎΡ‚ Π·Π½Π°ΠΊΠ° Ρ€Π°Π²Π½ΠΎ находится rvalue, Π° конструктор ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ копирования ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ с rvalue.

Π Π΅Π·ΡŽΠΌΠΈΡ€ΡƒΡ послСдниС Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Ρ€Π°Π·Π΄Π΅Π»Π° ΡΡ‚Π°Ρ‚ΡŒΠΈ:

  • C++ позволяСт вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΎΡ‚ Π½Π΅Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… (rvalue ΠΎΡ‚ lvalue);
  • позволяСт ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° эти Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹;
  • Π² случаС, Ссли ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΈΡ… для присваивания ΠΈΠ»ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, C++ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ конструктор Π»ΠΈΠ±ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π΅Π»Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΡƒΠ³ΠΎΠ΄Π½ΠΎ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π·Π°Π±ΠΈΡ€Π°Ρ‚ΡŒ рСсурсы Ρƒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, β€œΠ»ΠΎΠΌΠ°Ρβ€ ΠΈ β€œΠΏΠΎΡ€Ρ‚Ρβ€ Π΅Π³ΠΎ, Π½ΠΎ избСгая ΠΏΡ€ΠΈ этом ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ³ΠΎ копирования. β€œΠ˜ΡΠΏΠΎΡ€Ρ‡Π΅Π½Π½Ρ‹ΠΉβ€ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ сдСлал Π±Ρ‹ ΠΈ Π½Π΅ Π±ΡƒΠ΄ΡŒ ΠΎΠ½ β€œΠΈΡΠΏΠΎΡ€Ρ‡Π΅Π½Π½Ρ‹ΠΌβ€, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ – уничтоТаСтся (Π½Π° Ρ‚ΠΎ ΠΎΠ½ ΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ).

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΈ конструктор ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ копирования Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ ΠΊΠ°ΠΊ noexcept.

Π‘Ρ‚ΠΎΠΈΡ‚ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, извСстноС ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ Ρ‚Ρ€Ρ‘Ρ…, становится ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΠΌ пяти [9]: Ссли Π²Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚Π΅ Π² вашСм классС ΠΎΠ΄ΠΈΠ½ ΠΏΡƒΠ½ΠΊΡ‚ ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ списка, Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ всС ΠΏΡΡ‚ΡŒ:

  • конструктор копирования;
  • конструктор пСрСмСщСния;
  • ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ копирования;
  • ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния;
  • дСструктор.
ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
На самом Π΄Π΅Π»Π΅, ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Π°Ρ рСализация copy-and-swap idiom совмСщаСт ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ копирования ΠΈ пСрСмСщСния [10].

Π’Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΡŒ навСрняка задался вопросом, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ, Ссли класс содСрТит поля Π½Π΅ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, std::string), Π½Π΅ ΡΠ²Π»ΡΡŽΡ‰ΠΈΠ΅ΡΡ указатСлями, вСдь Π² Ρ‚Π°ΠΊΠΎΠΌ случаС ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ std::swap ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅*. Для Ρ‚Π°ΠΊΠΈΡ… ситуаций Π‘++11 ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ Π½Π°ΠΌ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡβ€¦

std::move

std::move [11] – это функция ΠΈΠ· стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, опрСдСлённая Π² Ρ…Π΅Π΄Π΅Ρ€Π΅ <utility>, которая позволяСт Π²Π·ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΡƒΠ³ΠΎΠ΄Π½ΠΎ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, lvalue), ΠΈ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈΠ· этого rvalue (xvalue, Ссли Π±Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΡ‡Π½Ρ‹ΠΌ).

ΠšΡ€ΡƒΡ‚ΠΎ... И Ρ‡Ρ‚ΠΎ это Π½Π°ΠΌ Π΄Π°Ρ‘Ρ‚? Π­Ρ‚ΠΎ Π΄Π°Ρ‘Ρ‚ Π½Π°ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, rvalue-ссылок Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρƒ нас Π½Π΅Ρ‚.

Допустим, наш класс X ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΠΎΠ»Π΅ Ρ‚ΠΈΠΏΠ° std::string. Как Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ конструктор ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ?

Листинг 5
        X(X&& x) : stringField(std::move(x.stringField)) noexcept {
    std::swap(resource, copy.resource);
}

X& operator=(X&& x) noexcept {
    stringField = std::move(x.stringField);
    std::swap(resource, copy.resource);

    return *this;
}
    

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π² конструкторС пСрСмСщСния для поля Ρ‚ΠΈΠΏΠ° std::string (stringField) вызываСтся конструктор пСрСмСщСния класса std::string, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ² std::move β€œΡΠ΄Π΅Π»Π°Π»β€ ΠΈΠ· x.stringField rvalue! Π’ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π΅ пСрСмСщСния для stringField вызываСтся ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния std::string, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ² std::move β€œΡΠ΄Π΅Π»Π°Π»β€ ΠΈΠ· x.stringField rvalue.

Π‘ Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния сСмантики, ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° Π² std::move позволяСт ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Ρ‡ΡŒΠΈ рСсурсы ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½Ρ‹.

std::move Ρ‚Π°ΠΊΠΆΠ΅ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² совокупности с ΡƒΠΌΠ½Ρ‹ΠΌΠΈ указатСлями (std::unique_ptr), ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΡ‹ Ρ‚ΠΎΠΆΠ΅ писали.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅*
ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Π½Π΅ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ Π±Ρ‹, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ std::swap Ρ‚ΠΎΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ std::move.
Π£Ρ‚Π΅ΡˆΠ΅Π½ΠΈΠ΅
Π’Π΅ΠΌΠ° move semantics Π² C++ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΈΠ²Π½ΠΎ нСпростая. Π­Ρ‚ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, Ссли Π²Ρ‹ Π½Π΅ всё поняли с ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ€Π°Π·Π°. ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ Π½Π°ΡˆΡƒ ΡΡ‚Π°Ρ‚ΡŒΡŽ, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΡΡ‚Π°Ρ‚ΡŒΡΠΌ ΠΏΠΎ этой Ρ‚Π΅ΠΌΠ΅ ΠΈ всё станСт Π½Π° свои мСста.

Π’Ρ‹Π²ΠΎΠ΄

Move semantics проявляСтся лишь Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹Ρ… случаях. Move semantics позволяСт Π·Π°Π±ΠΈΡ€Π°Ρ‚ΡŒ рСсурсы Ρƒ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Π² скором Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½Ρ‹, Ρ‚Π΅ΠΌ самым избСгая лишнСго копирования. ΠžΡΠ½ΠΎΠ²Π½Ρ‹ΠΌΠΈ инструмСнтами языка ΠΈ стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ move semantics ΡΠ²Π»ΡΡŽΡ‚ΡΡ:

  • ссылки Π½Π° rvalue;
  • конструктор ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния;
  • std::move.

ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ пСрСмСщСния вызываСтся, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ инициализируСтся rvalue, ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния – ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ присваиваСтся rvalue. std::move ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, рСсурсы ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½Ρ‹, прСвращая эти ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π² rvalue (xvalue).

НС рассмотрСнными ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ Ρ‚Π΅ΠΌΡ‹ rvalue-ссылок Π² контСкстС C++ шаблонов, Π² частности, Ρ‚Π΅ΠΌΡ‹ perfect forwarding ΠΈ std::forward [12], Ρ‚Π΅ΠΌΠ° copy/move elision ΠΈ RVO [13], Π° Ρ‚Π°ΠΊΠΆΠ΅ тонкая Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ C++ – ref-qualified ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ [14].

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

Π’ΠΠšΠΠΠ‘Π˜Π˜

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ вакансию
Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ C++
Москва, ΠΏΠΎ ΠΈΡ‚ΠΎΠ³Π°ΠΌ собСсСдования

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•