当前位置:  开发笔记 > 编程语言 > 正文

移动语义如何保留临时变量的数据?

如何解决《移动语义如何保留临时变量的数据?》经验,为你挑选了1个好方法。

我正在读这篇文章:什么是移动语义?

请注意,移动构造函数的帖子中给出的示例是:

string(string&& that)  
{
    data = that.data;
    that.data = nullptr;
}

当我们string a(x+y)用来构造一个新的字符串时,我发现它很混乱.由于结果x+y是一个临时变量,它很快就会被破坏.这意味着复制指针(data = that.data)确实会复制一个悬空指针,原始数据(应该存储在x+y函数调用完成后清理的堆栈帧中)被销毁.似乎设置that.data为nullptr无济于事,因为堆栈框架无论如何都会被清理干净.

任何人都可以解释为什么这不是一个问题?c ++如何实际处理这种情况?



1> rodrigo..:

当你这样做时:

string a(x + y);

它相当于:

string temp(x + y);
string a(move(temp));
//destroy temp

您引用的移动构造函数的相关代码采用aas thisthatas temp,因此可以将其内联为:

string temp(x + y);
string a(/*uninitialized*/);
a.data = temp.data;
temp.data = nullptr;
//destroy temp

正如你所看到的那样,temp.data那个被取消的那个,所以析构函数temp变成了无操作,实际的数据在里面存活a,正如预期的那样.

看起来你的困惑来自于它的起源data.在最简单的string实现中,string::data始终是动态分配的内存块:

string(const char *str)
{
    size_t len = strlen(str);
    data = new char[len + 1];
    strcpy(data, len);
}   
~string()
{
    delete[] data;
}

即使string被分配在堆栈,如tempa,甚至xy他们的data内存块是动态的.

真实的,实际的string实现通常进行非动态短字符串优化.但是如果你这样做,那么移动构造函数(以及任何其他成员函数)将会更复杂一些.

推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有