Consider this code:
#include <iostream>
#include <string>
using namespace std;
class Movable {
public:
Movable(const string& name) : m_name(name) { }
Movable(const Movable& rhs) {
cout << "Copy constructed from " << rhs.m_name << endl;
}
Movable(Movable&& rhs) {
cout << "Move constructed from " << rhs.m_name << endl;
}
Movable& operator = (const Movable& rhs) {
cout << "Copy assigned from " << rhs.m_name << endl;
}
Movable& operator = (Movable&& rhs) {
cout << "Move assigned from " << rhs.m_name << endl;
}
private:
string m_name;
};
int main() {
Movable obj1("obj1");
Movable obj2(std::move(obj1));
obj2 = std::move(obj1); // For demostration only
const Movable cObj("cObj");
Movable tObj(std::move(cObj));
tObj = std::move(cObj); // For demonstration only
}
Its output is:
Move constructed from obj1
Move assigned from obj1
Copy constructed from cObj
Copy assigned from cObj
As you can see, in these lines,
Movable tObj(std::move(cObj));
tObj = std::move(cObj); // For demonstration only
I intend to move cObj to tObj (the second move using the assignment operator is purely intended for demonstration). However, as you can see in the output, cObj is only copied to tObj.
The above example is only a demonstration and I do not know of any practical usage for this. But I will ask:
- Can I move a
constobject? - If I can, is it safe to do it?
ADDITIONAL: I forgot to ask. If I can move a const object, how should I do it? (const_cast?)
Sure, as long as the object’s non-
mutablestate doesn’t change as a result of being moved from.Perhaps you have an object that corresponds to file content, or a database record. And it caches that data when accessed, in a
mutablemember. Now, you could move that object by stealing its cached data, without actually modifying the object. So it would make sense (insofar as it makes sense for the object to be movable at all) for that object to have move constructor and move assignment operator that takeconst Record&&.This is perfectly legal, section 12.8p3 of the C++11 Standard provides that:
and p19:
In this way, you could move a
constobject,reopenthe newcopywhatever-you-call-an-instance-created-via-move, thus reusing the buffer space for something else and avoiding a new allocation, while leaving the old object intact and ready to return its content (by hitting the disk or database again) if required.