I create a class string by defining default, copy & move constructor. I try to create objects expecting each constructor to be invoked. As expected, the default & copy constructor are invoked, but when I pass a rvalue(temporary object), I still see move constructor NOT being invoked.
#include <iostream>
#include <cstdlib>
#include <cstring>
class string
{
char * data;
public:
string(const char * p = nullptr)
{
if(p == nullptr) return;
std::cout << "string(const char * p)" << std::endl;
size_t size = strlen(p) + 1;
data = new char[size];
memcpy(data, p, size);
}
~string()
{
std::cout << "~string() - " << data << std::endl;
delete[] data;
}
string(const string & that)
{
std::cout << "string(const string &)" << std::endl;
size_t size = strlen(that.data) + 1;
data = new char[size];
memcpy(data, that.data, size);
}
string(string && that)
{
std::cout << "string(string && )" << std::endl;
data = that.data;
that.data = nullptr;
}
void showData() { std::cout << data << std::endl; }
string operator+(const string & other)
{
size_t datasize = strlen(data);
size_t othersize = strlen(other.data);
size_t totalsize = datasize + othersize + 1;
char * sData = new char[totalsize];
memcpy(sData, data, strlen(data));
memcpy(sData+datasize, other.data, totalsize-datasize);
string s(sData);
delete[] sData;
return s;
}
string & operator=(string that)
{
char * tmp = data;
data = that.data;
that.data = tmp;
return *this;
}
};
int main()
{
string s1{"stackoverflow"}; // s1
string s2{s1}; // s2
string s3{string("stack")+string("exchange")}; // s3
}
At s1: default constructor is being called as expected.
At s2: copy constructor is invoked, also as expected.
At s3: I'm passing a temporary object. So, I expect move constructor be invoked, but default constructor being called.
I'm unable to comprehend what I'm missing. Kindly help, thanks.
Indeed it behaves as you say with GCC and Clang, but the move constructor is called with VC++. Looks like a bug, then you should move explicitly with std::move().