![](/img/trans.png)
[英]Why isn't the copy-constructor called when passing rvalue by value to function
[英]Despite passing an rvalue, why isn't my move constructor getting called?
我通过定义默认,复制和移动构造函数来创建一个类字符串。 我尝试创建期望每个构造函数被调用的对象。 正如所料,默认&复制构造函数被调用,但是当我传递一个rvalue(临时对象)时,我仍然看到移动构造函数未被调用。
#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
}
在s1 :正在按预期调用默认构造函数 。
在s2 :调用复制构造函数 ,也如预期的那样。
在s3 :我正在传递一个临时物体。 所以,我希望调用move构造函数 ,但调用默认构造函数 。
我无法理解我所缺少的东西。 请帮助,谢谢。
您已将data
定义为char *
。
string(string && that)
{
std::cout << "string(string && )" << std::endl;
data = that.data;
that.data = nullptr;
}
表示移动构造函数中的data
“副本”不是深层副本。
编辑:现在,这没关系,因为你可以“消除”右边界,但是,当它破坏你使用nullptr
这样做时:
你打电话的时候
std::cout << "~string() - " << data << std::endl;
在析构函数中,data为null,您有未定义的行为。 什么事情都可能发生。
实际上它的行为和GCC和Clang一样,但是用VC ++调用移动构造函数。 看起来像一个bug,然后你应该用std :: move()显式移动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.