I'm currently studying move semantics in C++, and I faced an unexpected behavior. Here is a Test class with different constructors declared.
#include <iostream>
#include <string>
using namespace std;
class Test {
public:
Test(const std::string &s = "") : s_(s) {
cout << "Constructor " << s_ << endl;
}
Test(const std::string &&s)
: s_(std::move(s)) {
cout << "Move constructor " << s_ << endl;
}
Test(const Test &t) {
cout << "Copy " << t.s_ << " to " << s_ << endl;
s_ = "copy " + t.s_;
}
Test(const Test &&t) noexcept
: s_(std::move(t.s_)) {
cout << "Move " << t.s_ << " to " << s_ << endl;
}
Test& operator=(const Test &t) {
cout << "operator= " << s_ << " = " << t.s_ << endl;
s_ = "= " + t.s_;
return *this;
}
~Test() {
cout << "Destructor " << s_ << endl;
}
private:
std::string s_;
};
And a piece of code to check, how move works:
int main() {
Test t1{"1"};
Test t2(std::move(t1));
std::string str3("t3");
Test t3(std::move(str3));
cout << "str str3 after std::move " << str3 << endl;
std::string sss("e");
std::string fff(std::move(sss));
cout << "str sss after std::move " << sss << endl;
return 0;
}
After executing this code the output is:
Move constructor 1
Move 1 to 1
Move constructor t3
str str3 after std::move t3
str sss after std::move
Destructor t3
Destructor 1
Destructor 1
So it seems that t1 and str3 variables still have it's values, though it should be absent after calling the move constructor in std::string the same way it happens with sss and fff in a case with strings, not aggregated to a class. But it seems that they're just copied.
Is there something I missed?