Қозғалатын зат объектіні қолайлы күйде қалдырады ма?

Менде екі вектор бар және бірін екіншісіне жылжытыңыз: v1 = std :: move (v2) ; v2 бұдан кейін қолданылатын күйде болады ма?

14
Бұл stackoverflow.com/q/7027523/576911 көшірмесіне ұқсайды. Бұл жауапты қараңыз: stackoverflow.com/questions/7027523/…
қосылды автор Howard Hinnant, көзі

3 жауаптар

N3290-дан, 17.6.5.15 Кітапхананың түрлерінен көшірілді [lib.types.movedfrom]

  1. Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

Мемлекет жарамды болғандықтан, бұл v2 (мысалы, белгілі бір күйге оралуы мүмкін) тағайындау арқылы қауіпсіз түрде жұмыс істей алатыныңызды білдіреді. Алайда, ол анықталмаған болғандықтан, мысалы, егер бұл күйде болатын болса (мысалы, бағдарламаны бұзбайтын болса) v2.empty() үшін қандай да бір мәнге сүйенуге болмайды.

Көшірудің семантикасы («Объектілерден жылжыту жарамды, бірақ анықталмаған күйінде қалдырылған)» деген аксиома стандартты кітапхананың компоненттеріне ғана емес, барлық кодқа ұмтылуы керек екенін ескеріңіз. Көшіру конструкторларының семантикасына ұқсас көшірмесін жасау керек, бірақ міндетті емес.

22
қосылды
+1, бірақ жазылған жолы v2 = std :: vector {}; кейін v2
қосылды автор Gabriel, көзі
@Gabriel Жақсы нүкте, редакция тәртібі бойынша.
қосылды автор Luc Danton, көзі

Жоқ, ол анықталмаған күйде қалды.

open-std-org a> мақала -

.. move() өз мақсатына дәлелін береді, бірақ оның көзінің мәнін сақтауға міндетті емес . Осылайша, вектордың қозғалысы() барлық элементтерді көшіруге жол бермеу үшін өз дәлелін нөлдік сыйымдылық векторы ретінде қалдыруы мүмкін. Басқаша айтқанда, көшу ықтимал деструктивті оқылуы.

7
қосылды
міндетті жарамды болуы керек. Олай болмаған жағдайда, нысан нəтиже бермей қалғанда не болады. Мүмкін, ол өз деректерінде ештеңе болмайды, бірақ олай болса да, ол жарамды болады.
қосылды автор Damon, көзі
Ол белгісіз , бірақ жарамды күйінде қалады. Яғни, сіз әлі де нысанды объектінің жарамдылығы туралы тек қана алғышарттармен қолдануға болады. Мысалы, vector :: clear() деп аталатын вектордан белгілі бір күйге өту үшін қоңырау шалуға болады, содан кейін оған нысандарды кірістіре бастаңыз.
қосылды автор bames53, көзі
Қолданылудың бірнеше (абстрактылы) деңгейі бар. Тілге қатысты болсақ, объекті жылжытылғаннан кейін объекті әлі бар болса, оны жойғышты анықталмаған мінез-құлықсыз және т.б. шақыруға болады. Алайда, келісім-шарттың нысаны өзгерген кезде өзгеруі мүмкін . Мысалы, вектордың нөлге тең болғандығы (сыйымдылығы жоқ) вектордың жарамды C ++ векторы болып табылады, бірақ вектордағы белгілі бір элементті орнататын әдіске ие объекті (қазір жарамсыз) болжамды вектордың нақты мөлшері болуы керек, ол ...
қосылды автор rwong, көзі
... тыйым салынған операцияға айналады (UB себеп болады). Мұндай мәліметтер объектіні іске асырушы тарапынан құжатталуы тиіс. Орындаушы, егер қажет болса, объектінің қол жетімділігін қалпына келтіру үшін құжатталған тәсілмен қамтамасыз етуі керек.
қосылды автор rwong, көзі

Егер Сіз жылжытқаннан кейін v2 қолдансаңыз болса, сіз келесідей нәрсе жасағыңыз келеді:

v1 = std::move(v2);
v2.clear();

Бұл кезде v1 v2 және v2 бастапқы мазмұндары жақсы анықталған күйде болады. Бұл барлық STL контейнерлерінде жұмыс істейді (және бұл жолдар үшін), және сіз өзіңіздің қозғалыс-семантиканы қолдайтын өз сыныптарыңызды жүзеге асырсаңыз, сіз ұқсас нәрсе жасауға тырысқыңыз келуі мүмкін.

Егер STL-тің нақты іске асырылуы шын мәнінде нысанды бос күйде қалдырса, онда екінші clear() мәні негізінен no-op болады. Шын мәнісінде, егер бұлай болса, бұл компилятордың қозғалыстан кейін clear() жою үшін заңды оңтайландыру болар еді.

0
қосылды