标签:des blog 使用 os io 2014 问题 cti
int&& rvalue_ref = 99;下面就是一个右值引用例子:
#include<iostream>
void f(int& i) {
std::cout<<"lvalue ref: "<<i<<std::endl;
}
void f(int&& i) {
std::cout<<"rvalue ref: "<<i<<std::endl;
}
int main()
{
int i=99;
f(i); //lvalue ref called
f(99); //rvalue ref called
f(std::move(i)); //rvalue ref called
return 0;
} 运行结果为:#include<iostream>
int getValue() {
int i = 22;
return i;
}
int main() {
std::cout<<getValue()<<std::endl;
return 0;
} getValue()就是一个右值。注意:返回的这个值并不是i的引用,而是一个临时值。const int& val = getValue(); // OK int& val = getValue(); // Wrong!但是,C++11中的右值引用允许我们绑定一个mutable引用到rvalue,但不是lvalue。换言之,右值引用可以完美的判断一个值是否为临时对象。
const int&& val = getValue(); // OK int&& val = getValue(); // OK下面进行一下比较:
void printReference (const int& value)
{
std::cout << value;
}
void printReference (int&& value)
{
std::cout << value;
} 第一个函数的参数类型为const lvalue, 它可以接收任何传入参数,无论是rvalue还是lvalue. 但是,第二个函数只能接收右值引用。#include<iostream>
void printRef(int& value) {
std::cout<<"lvalue: value = "<<value<<std::endl;
}
void printRef(int&& value) {
std::cout<<"rvalue: value = "<<value<<std::endl;
}
int getVal() {
int tmp = 88;
return tmp;
}
int main(){
int i = 11;
printRef(i);
printRef(getVal()); //printRef(88);
return 0;
} 运行结果为:#include<iostream>
#include<algorithm>
#include<vector>
class Dummy {
public:
explicit Dummy(size_t length):_length(length), _data(new int[length]) {
std::cout<<"Dummy(size_t).length = "<<_length<<"."<<std::endl;
}
~Dummy() {
std::cout<<"~Dummy().length = "<<_length<<"."<<std::endl;
if(_data!=NULL){
std::cout<<"delete resource."<<std::endl;
delete _data;
}
}
Dummy(const Dummy&other):_length(other._length),_data(new int[other._length]) {
std::cout<<"Dummy(const &Dummy).length = "<<other._length<<".Copying resource."<<std::endl;
std::copy(other._data, other._data+_length, _data);
}
//Copy assignment operator
Dummy& operator=(const Dummy& other) {
std::cout<<"operator=(const Dummy&).length = "<<other._length<<". Copying resource."<<std::endl;
if(this != &other) {
delete _data;
_length = other._length;
_data = new int[_length];
std::copy(other._data, other._data+_length, _data);
}
return *this;
}
//Move constructor
Dummy(Dummy&& other):_length(0),_data(NULL) {
std::cout<<"Dummy(Dummy&&).length = "<<other._length<<". Moving resource."<<std::endl;
//copy the data pointer and its length from the source object
_data = other._data;
_length = other._length;
//release the data pointer from the source object so that the destructor does not free
//the memory multiple times.
other._data = NULL;
other._length = 0;
}
//Move assigment operator
Dummy& operator=(Dummy&& other) {
std::cout<<"operator=(Dummy&&).length = "<<other._length<<"."<<std::endl;
if(this != &other) {
delete _data;
//copy the data pointer and its length from the source object
_data = other._data;
_length = other._length;
//release the data pointer from the source object so that the destructor does not free
//the memory multiple times
other._data = NULL;
other._length = 0;
}
return *this;
}
private:
size_t _length;
int* _data;
};
int main() {
std::vector<Dummy> vec;
vec.push_back(Dummy(55));
vec.push_back(Dummy(77));
//insert a new element into the second position of the vector
vec.insert(vec.begin()+1, Dummy(66));
return 0;
} 运行结果为:Dummy(Dummy&& other) noexcept // C++11 - specify non-exception throwing function
{
_date = other._data; // shallow copy
other._date = nullptr;
} 注意:上面函数没有分配任何新的资源,只是将内容移动了而不是拷贝: other中的内容移到了一个新成员里边,然后other中的内容被清除了。它占用了other的资源并且将other设置为了默认构造函数时的状态。最重要的事实是没有内容的分配开销。我们只是分配了一个地址,只需很少的几个机器指令即可实现。Dummy& operator=(Dummy&& other) noexcept
{
_data = other._data;
other._data = nullptr;
return *this;
} 移动赋值运算符与拷贝构造函数类似,除了转移source object之前,它会释放object所拥有的资源。步骤如下:std::vector<A> vec; vec.push_back(A(55)); vec.push_back(A(77));这两个push_back,实际上都使用的push_back(T&&), 因为传入的参数是右值。push_back(T&&)会将参数中的资源,移动到vector中的对象A, 使用的是A的移动构造函数。在C++03中,相同的这段代码会进行参数的赋值,因为会调用参数的拷贝构造函数。
std::vector<A> vec; A obj(25); // lvalue vec.push_back(obj); // push_back(const T&)不过,我们可以使用static_cast将左值引用转换为右值引用,使得调用的是push_back(T&&)。
// calls push_back(T&&) vec.push_back(static_cast<A&&>(obj));另外一种办法是,使用std::move()来实现:
// calls push_back(T&&) vec.push_back(std::move(obj));总结起来,push_back(T&&)看似总是最近选择,因为它减少了不必要的拷贝开销。然而,需要记住的是push_back(T&&)总会清空传入的参数。如果需要在执行一个push_back()操作后,仍然保持参数原始状态,则还是需要选择拷贝语义(拷贝构造函数),而不是移动语义。
#include<iostream>
class Dummy
{
public:
//constructor
explicit Dummy(size_t length):_length(length),_data(new int[length]) { }
//move constructor
Dummy(Dummy&& other) {
_data = other._data;
_length = other._length;
other._data = nullptr;
other._length = 0;
}
//move assignment operator
Dummy& operator= (Dummy&& other) noexcept {
_data = other._data;
_length = other._length;
other._data = nullptr;
other._length = 0;
return *this;
}
void swap(Dummy& other) {
Dummy tmp = std::move(other);
other = std::move(*this);
*this = std::move(tmp);
}
int getLength() { return _length; }
int* getData() { return _data; }
private:
size_t _length;
int* _data;
};
int main()
{
Dummy a(11),b(22);
std::cout<<a.getLength()<<" "<<b.getLength()<<std::endl;
std::cout<<a.getData()<<" "<<b.getData()<<std::endl;
a.swap(b);
std::cout<<a.getLength()<<" "<<b.getLength()<<std::endl;
std::cout<<a.getData()<<" "<<b.getData()<<std::endl;
return 0;
} 运行结果为:C++11线程指南(四)--右值引用与移动语义,布布扣,bubuko.com
标签:des blog 使用 os io 2014 问题 cti
原文地址:http://blog.csdn.net/shltsh/article/details/38406729