Двойной ход на том же объекте копирует слева направо?

Я только начинающий в операции перемещения в C ++ 11, так что играть с ним. Но нашел то, что я не в состоянии понять.

#include <iostream>
using namespace std;

class A{
public:
A(){cout << "default ctor" << endl;}
A(const string& str):_str{str}{cout << "parameter ctor" << endl;}
A(A&& obj):_str{std::move(obj._str)}{cout << "move ctor" << endl;}
A& operator =(A&& rhs){_str = std::move(rhs._str);cout << "move assignment operation" << endl; return *this;}
void print(){cout << _str << endl;}
private:
string _str;
};

int main(){
A a("rupesh yadav"); // parameter ctor
A b(std::move(a));   // move ctor

cout << "print a: ";
a.print();           // NOT printing  --> CORRECT!!
cout << "print b: ";
b.print();           // printing      --> CORRECT!!

b = std::move(a);    // i don't know may be silly but still lets do it WHY NOT!!!, could be just mistake??

cout << "print a: ";
a.print();           // printing      --> WRONG!!
cout << "print b: ";
b.print();           // NOT printing  --> WRONG!!
}

Я ожидал, что b = std::move(a) Операция будет вести себя иначе, потому что я применяю движение на объекте второй раз, но он копирует левый боковой объект б на правой стороне объекта , эту часть я не понимаю.

Или я сделал что-то не так в программировании.
Пожалуйста, помогите, если я делаю что-то не так в процессе перемещения.

РЕДАКТИРОВАТЬ: Я знаю, что это неопределенное поведение. Я сомневаюсь, что если я сделаю это снова, то это будет копирование с объекта для объекта б, и если я снова сделаю то же самое, то скопирую объект б для объекта ?

Следовательно, это копирование формы слева направо и справа налево, почему?

4

Решение

Вы не можете двинуться с одного и того же объекта дважды.

После того, как вы впервые переехали a в b, a имел «допустимое, но неопределенное состояние» (не могу вспомнить точную терминологию). Затем вы попытались двигаться a в b снова! Теперь, черт возьми, вырвался (Я подозреваю, что внутренне указатели данных только что поменялись местами.)

Просто не делай этого. Я не вижу причин хотеть.

5

Другие решения

Ничто не мешает вам двинуться с объекта дважды. Стандартные объекты библиотеки должны быть оставлены в «допустимом, но неопределенном» состоянии при перемещении из. Единственное условие: «инварианты объекта соблюдаются, а операции над объектом ведут себя так, как указано для его типа». 17.3.28. Например, конструктор перемещения для std::string говорит:

basic_string(const basic_string& str);

basic_string(basic_string&& str) noexcept;

2 Последствия: Строит объект класса basic_string как указано
в таблице [tab: strings.ctr.cpy]. Во втором классе str остается в
допустимое состояние с неопределенным значением.

Конструктор перемещения не имеет предварительных условий, и повторное перемещение из него не нарушит его инвариантов. Кроме того, поскольку это четко обозначено в стандарте, по определению это не неопределенное поведение. По упущению можно утверждать, что нарушая инварианты std::string однако неопределенное поведение, но это приводит нас к:

Звонит operator<< на std::string запрещено? Описание от cppreference говорит:

Ведет себя как
FormattedOutputFunction.
После построения и проверки сторожевого объекта, определяется
Выходной формат дополняется следующим образом:

  • Если str.size() не менее чем os.width(), использует диапазон [str.begin(), str.end()) как есть

  • В противном случае, если (os.flags() & ios_base::adjustfield) == ios_base::left, мест os.width()-str.size() копии
    os.fill() символ после последовательности символов

  • В противном случае места os.width()-str.size() копии os.fill() символ перед последовательностью символов

size(), begin() а также end() не имеют предварительных условий, поэтому код совершенно безопасен.

2

По вопросам рекламы [email protected]