Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π―Π·Ρ‹ΠΊ программирования C++. ΠŸΡΡ‚ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 184

Автор Π‘Ρ‚Π΅Π½Π»ΠΈ Π›ΠΈΠΏΠΏΠΌΠ°Π½

Ѐункция заканчиваСтся Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ clear() ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° m.folders. Π˜Π·Π²Π΅ΡΡ‚Π½ΠΎ, Ρ‡Ρ‚ΠΎ послС пСрСмСщСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ m.folders Π²ΠΏΠΎΠ»Π½Π΅ допустим, Π½ΠΎ Π΅Π³ΠΎ содСрТимоС нСпрСдсказуСмо. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ дСструктор класса Message ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Π΅Ρ‚ Π½Π°Π±ΠΎΡ€ folders, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Π½Π°Π±ΠΎΡ€ пуст.

ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ пСрСмСщСния класса Message Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ move(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ содСрТимоС ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ свой Ρ‡Π»Π΅Π½ folders:

Message::Message(Message &&m): contents(std::move(m.contents)) {

 move_Folders(&m); // ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ folders ΠΈ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Folder

}

Π’ Ρ‚Π΅Π»Π΅ конструктора происходит Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ move_Folders(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° m ΠΈ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Π΄Π°Π½Π½ΠΎΠ΅ сообщСниС.

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ нСпосрСдствСнно провСряСт случай присвоСния сСбя сСбС:

Messages Message::operator=(Message &&rhs) {

 if (this != &rhs) { // прямая ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° присвоСния сСбя сСбС

  remove_from_Folders();

  contents = std::move(rhs.contents); // присвоСниС ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ

  move_Folders(&rhs); // ΡΠ±Ρ€ΠΎΡΠΈΡ‚ΡŒ ΠΏΠ°ΠΏΠΊΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° это

                      // сообщСниС

 }

 return *this;

}

Подобно Π»ΡŽΠ±Ρ‹ΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌ присвоСния, ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΏΡ€Π΅ΠΆΠ½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅ Π»Π΅Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π°. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π»Π΅Π²ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄Π° Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ удалСния ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° это сообщСниС ΠΈΠ· ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΏΠ°ΠΏΠΎΠΊ, Ρ‡Ρ‚ΠΎ ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ remove_from_Folders(). ПослС удалСния ΠΈΠ· ΠΏΠ°ΠΏΠΎΠΊ происходит Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ move(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ contents ΠΈΠ· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° rhs Π² this. ΠžΡΡ‚Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ move_Folders(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Folder.

Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ пСрСмСщСния

Ѐункция reallocate() класса StrVec (см. Ρ€Π°Π·Π΄Π΅Π» 13.5) использовала Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ construct() Π² Ρ†ΠΈΠΊΠ»Π΅ for для копирования элСмСнтов ΠΈΠ· ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΉ памяти Π² Π½ΠΎΠ²ΡƒΡŽ. ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²ΠΎΠΉ Ρ†ΠΈΠΊΠ»Ρƒ Π±Ρ‹Π» Π±Ρ‹ просто Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ uninitialized_copy() для создания Π½ΠΎΠ²ΠΎΠ³ΠΎ пространства Π² памяти. Однако функция uninitialized_copy() Π΄Π΅Π»Π°Π΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚ΠΎ, ΠΎ Ρ‡Π΅ΠΌ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ Π΅Π΅ имя: ΠΎΠ½Π° ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ элСмСнты. НСт Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для пСрСмСщСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² ΠΏΡƒΡΡ‚ΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ.

ВмСсто Π½Π΅Π΅ новая Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° опрСдСляСт Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° пСрСмСщСния (move iterator) (см. Ρ€Π°Π·Π΄Π΅Π» 10.4). Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ Π΅ΠΌΡƒ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, измСняя ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π΅Π³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° обращСния ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ обращСния ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ссылку Π½Π° l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта. Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ², ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ обращСния ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° пСрСмСщСния Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ссылку Π½Π° r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

ΠžΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ прСобразуСтся Π² ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ make_move_iterator(), которая ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния.

ВсС ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚, ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ эти ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ², ΠΏΠ°Ρ€Ρƒ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² пСрСмСщСния Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡƒ. Π’ частности, ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ пСрСмСщСния ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡƒ uninitialized_copy():

void StrVec::reallocate() {

 // Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΄Π²ΠΎΠ΅ большС пространства, Ρ‡Π΅ΠΌ для Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ

 // количСства элСмСнтов

 auto newcapacity = size() ? 2 * size() : 1;

 auto first = alloc.allocate(newcapacity);

 // ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ элСмСнты

 auto last = uninitialized_copy(make_move_iterator(begin()),

                                make_move_iterator(end()),

                                first);

 free();           // ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΏΡ€Π΅ΠΆΠ½Π΅Π΅ пространство

 elements = first; // ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ

 first_free = last;

 cap = elements + newcapacity;

}

Алгоритм uninitialized_copy() Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ construct() для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта исходной ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ элСмСнт ΠΏΠΎ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. Для Π²Ρ‹Π±ΠΎΡ€Π° элСмСнта ΠΈΠ· исходной ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π΄Π°Π½Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ обращСния ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π±Ρ‹Π» ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ пСрСмСщСния, ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ обращСния ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ссылку Π½Π° r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ функция construct() Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для создания элСмСнтов конструктор пСрСмСщСния.

Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ стандартная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π½Π΅ Π΄Π°Π΅Ρ‚ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΉ примСнимости всСх Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² с ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ пСрСмСщСния. Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° способно ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π», ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ пСрСмСщСния слСдуСт ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°ΠΌ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ ΡƒΠ²Π΅Ρ€Π΅Π½Ρ‹, Ρ‡Ρ‚ΠΎ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ элСмСнтам послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΎΠ½ присвоил этот элСмСнт ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π» Π΅Π³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Π‘ΠΎΠ²Π΅Ρ‚. НС слишком ΡΠΏΠ΅ΡˆΠΈΡ‚Π΅ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ΠΌ

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ состояниС ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° пСрСмСщСния Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎ, Π²Ρ‹Π·ΠΎΠ² для Π½Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ std::move() β€” опасная опСрация. Когда происходит Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ move(), слСдуСт Π±Ρ‹Ρ‚ΡŒ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ ΡƒΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° пСрСмСщСния Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.

Π’Π·Π²Π΅ΡˆΠ΅Π½Π½ΠΎ использованная Π² ΠΊΠΎΠ΄Π΅ класса, функция move() способна ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ сущСствСнный Π²Ρ‹ΠΈΠ³Ρ€Ρ‹Ρˆ Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. НСбрСТноС Π΅Π΅ использованиС Π² ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΌ ΠΊΠΎΠ΄Π΅ (Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΊΠΎΠ΄Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ класса), вСроятнСй всСго, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Π·Π°Π³Π°Π΄ΠΎΡ‡Π½Ρ‹ΠΌ ΠΈ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΌ ошибкам, Π° Π½Π΅ ΠΊ ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ прилоТСния.

Π—Π° ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ ΠΊΠΎΠ΄Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ класса, Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠ°ΠΊ конструкторы пСрСмСщСния ΠΈΠ»ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ присваивания ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ std::move() Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠΉ увСрСнности Π² нСобходимости пСрСмСщСния ΠΈ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ бСзопасным.

УпраТнСния Ρ€Π°Π·Π΄Π΅Π»Π° 13.6.2

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.49. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ конструктор пСрСмСщСния ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ Π² классы StrVec, String ΠΈ Message.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.50. Π‘Π½Π°Π±Π΄ΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ пСрСмСщСния класса String ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈ снова запуститС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈΠ· упраТнСния 13.48 Ρ€Π°Π·Π΄Π΅Π»Π° 13.6.1, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ использовался Π²Π΅ΠΊΡ‚ΠΎΡ€ vector<String>, ΠΈ посмотритС, ΠΊΠΎΠ³Π΄Π° Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ удаСтся ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ копирования.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.51. Π₯отя ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ unique_ptr Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ скопирован, Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 12.1.5 Π±Ρ‹Π»Π° написана функция clone(), которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΠ»Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ unique_ptr ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. ΠžΠ±ΡŠΡΡΠ½ΠΈΡ‚Π΅, ΠΏΠΎΡ‡Π΅ΠΌΡƒ эта функция допустима ΠΈ ΠΊΠ°ΠΊ ΠΎΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.52. ΠžΠ±ΡŠΡΡΠ½ΠΈΡ‚Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ, Ρ‡Ρ‚ΠΎ происходит ΠΏΡ€ΠΈ присвоСнии ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² класса HasPtr. Π’ частности, ΠΎΠΏΠΈΡˆΠΈΡ‚Π΅ шаг Π·Π° шагом, Ρ‡Ρ‚ΠΎ происходит со значСниями hp, hp2 ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ rhs Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π΅ присвоСния класса HasPtr.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.53. Π‘ Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠΉ эффСктивности ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присвоСния класса HasPtr Π½Π΅ ΠΈΠ΄Π΅Π°Π»Π΅Π½. ΠžΠ±ΡŠΡΡΠ½ΠΈΡ‚Π΅ ΠΏΠΎΡ‡Π΅ΠΌΡƒ. Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ для класса HasPtr ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присвоСния ΠΊΠΎΠΏΠΈΠΈ ΠΈ присваивания ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ ΠΈ сравнитС дСйствия, выполняСмыС Π² Π½ΠΎΠ²ΠΎΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π΅ присваивания ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ, с вСрсиСй ΠΊΠΎΠΏΠΈΠΈ ΠΈ ΠΎΠ±ΠΌΠ΅Π½Π°.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 13.54. Π§Ρ‚ΠΎ Π±Ρ‹ ΡΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ, Ссли Π±Ρ‹ ΠΌΡ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ для класса HasPtr, Π½ΠΎ Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ»ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΊΠΎΠΏΠΈΠΈ ΠΈ ΠΎΠ±ΠΌΠ΅Π½Π°? ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΊΠΎΠ΄ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ вашСго ΠΎΡ‚Π²Π΅Ρ‚Π°.

13.6.3. Бсылки Π½Π° r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹

ВсС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹, ΠΊΡ€ΠΎΠΌΠ΅ конструкторов ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² присвоСния, ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ ΠΏΠΎΠ»ΡŒΠ·Ρƒ ΠΈΠ· прСдоставлСния вСрсии копирования ΠΈ пСрСмСщСния. Π’Π°ΠΊΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ пСрСмСщСния ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Ρ‚Ρƒ ΠΆΠ΅ схСму ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², Ρ‡Ρ‚ΠΎ ΠΈ конструктор ΠΊΠΎΠΏΠΈΠΉ/пСрСмСщСния ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ присвоСния, β€” ΠΎΠ΄Π½Π° вСрсия ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ссылку Π½Π° константноС l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° вторая β€” ссылку Π½Π° Π½Π΅ константноС r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

НапримСр, Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹Π΅ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ push_back(), ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π΄Π²Π΅ вСрсии: ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΎΠ΄Π½ΠΎΠΉ являСтся ссылкой Π½Π° r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ β€” ссылкой Π½Π° константноС l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π‘ ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ X являСтся Ρ‚ΠΈΠΏΠΎΠΌ элСмСнта, эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ Ρ‚Π°ΠΊ:

void push_back(const X&); // ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅: привязка ΠΊ Π»ΡŽΠ±ΠΎΠΌΡƒ X

void push_back(X&&);      // ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅: привязка Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ измСняСмым

                          // r-значСниям Ρ‚ΠΈΠΏΠ° X

ΠŸΠ΅Ρ€Π²ΠΎΠΉ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ push_back() ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ любой ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΊ Ρ‚ΠΈΠΏΡƒ X. Π­Ρ‚Π° вСрсия ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ своСго ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. Π’Ρ‚ΠΎΡ€ΠΎΠΉ вСрсии ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ являСтся константой. Π­Ρ‚Π° вСрсия Ρ‚ΠΎΡ‡Π½Π΅Π΅ ΠΈ Π»ΡƒΡ‡ΡˆΠ΅Π΅ соотвСтствуСт нСконстантным r-значСниям ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ ΠΏΠΎΠ΄Π΄Π°ΡŽΡ‰Π΅Π³ΠΎΡΡ измСнСнию r-значСния (см. Ρ€Π°Π·Π΄Π΅Π» 13.6.2). Π­Ρ‚Π° вСрсия способна Π·Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ рСсурсы своСго ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°.