Может кто-нибудь объяснить, почему исходный объект, который передается новому объекту через std :: move, по-прежнему действует после?std :: move used, move constructor, но объект все еще действителен
#include <iostream>
class Class
{
public:
explicit Class(const double& tt) : m_type(tt)
{
std::cout << "defaultish" << std::endl;
};
explicit Class(const Class& val) :
m_type(val.m_type)
{
std::cout << "copy" << std::endl;
};
explicit Class(Class&& val) :
m_type(val.m_type)
{
m_type = val.m_type;
std::cout << "move: " << m_type << std::endl;
};
void print()
{
std::cout << "print: " << m_type << std::endl;
}
void set(const double& tt)
{
m_type = tt;
}
private:
double m_type;
};
int main()
{
Class cc(3.2);
Class c2(std::move(cc));
c2.print();
cc.set(4.0);
cc.print();
return 0;
}
Он выводит следующее:
defaultish
move: 3.2
print: 3.2
print: 4
Я бы ожидать, что вызовы cc.set() и cc.print() на провал ...
UPDATE Спасибо к ответам ниже, мы определили, что 1) я ничего не двигал в конструкторе перемещения, а 2) std::move()
на int или double ничего не делает, потому что более дорогое перемещение этих типов, чем просто копирование. Новый код ниже обновляет переменную частного члена класса, которая будет иметь тип std :: string вместо double, и правильно вызывает std :: move при установке этой переменной частного члена в конструкторе перемещения класса, в результате получается вывод, который показывает, как ЗППП :: переместить результаты в действительного, но неустановленное состоянии
#include <iostream>
#include <string>
class Class
{
public:
explicit Class(const std::string& tt) : m_type(tt)
{
std::cout << "defaultish" << std::endl;
};
explicit Class(const Class& val) :
m_type(val.m_type)
{
std::cout << "copy" << std::endl;
};
explicit Class(Class&& val) : m_type(std::move(val.m_type))
{
std::cout << "move: " << m_type << std::endl;
};
void print()
{
std::cout << "print: " << m_type << std::endl;
}
void set(const std::string val)
{
m_type = val;
}
private:
std::string m_type;
};
int main()
{
Class cc("3.2");
Class c2(std::move(cc));
c2.print();
cc.print();
cc.set("4.0");
cc.print();
return 0;
}
И, наконец, выход:
defaultish
move: 3.2
print: 3.2
print:
print: 4.0
Как правило, вы можете вызывать функции-члены на перемещенном объекте, который не имеет предварительных условий (включая назначение и уничтожение). –
Можете ли вы объяснить утверждение: «На самом деле вы ничего не двигали? Это потому, что я забыл удалить список инициализаторов? – Wond3rBoi
@ Wond3rBoi Вы использовали' m_type (val.m_type) 'вместо' m_type (std :: move (val ,m_type)) 'в вашем движении ctor. Однако это не делает ничего (для 'double'), как объяснено в этом ответе. – user2296177