1、左值与右值的区别:
左值:能别赋值的值;能取到地址的值,用&能取到地址,具有持久性;
右值:临时变量;不能用&取到地址;只是字面常量值
2、右值引用
一般用的是左值引用,用&标识
右值引用通过&&获得,只能绑定到将要销毁的对象
如下例子:在代码里面进行了标识:
class MemoryBlock {
public:
//构造器
explicit MemoryBlock(int length) : length_(length), data_(new int[length]()) {
}
virtual ~MemoryBlock() {
if (data_) {
delete[] data_;
data_ = nullptr;
}
}
//拷贝构造,左值引用
MemoryBlock(const MemoryBlock &src) : length_(src.length_), data_(new int[src.length_]()){
std::copy(src.data_, src.data_+length_, data_);
}
//普通的赋值,左值引用
MemoryBlock& operator=(const MemoryBlock &src) {
if (this != &src) {
delete[] data_;
length_ = src.length_;
data_ = new int[length_]();
std::copy(src.data_, src.data_+length_, data_);
}
return *this;
}
//移动构造器,右值引用
MemoryBlock(MemoryBlock&& src) : length_(src.length_),data_(src.data_) noexcept {
src.length_ = 0;
src.data_ = nullptr;
}
//移动赋值
MemoryBlock& operator=(MemoryBlock &&src) noexcept {
if (this != &src) {
delete[] data_;
length_ = src.length_;
data_ = src.data_;
//将传入的参数设置为空 释放传入的数据
src.length_ = 0;
src.data_ = nullptr;
}
return *this;
}
private:
int length_;
int *data_;
};
MemoryBlock f() {
return MemoryBlock(50);
}
int main()
{
std::cout << "11111111" << std::endl;
MemoryBlock a = f(); // 调用构造器
MemoryBlock b = a; //拷贝构造
MemoryBlock c = std::move(a);// 移动构造器,移动语义
a = f(); // 调用移动赋值运算符,移动语义
b = a; // 调用赋值运算符
c = std::move(a); // 调用移动赋值运算符,移动语义
return 0;
}
//移动构造器
MemoryBlock(MemoryBlock&& src) : length_(src.length_),data_(src.data_) noexcept {
src.length_ = 0;
src.data_ = nullptr;
}
- 、将入参传给成员
- 、释放传入的数据.
总结:移动构造、移动赋值仅仅是将原来存在的资源移动到其他的位置。因此其自身的资源将会被释放。