[abondoned]

参考1
参考2
参考3

参考4
参考5 :代码实现

概念理解

意义

消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。

能够更简洁明确地定义泛型函数。

左值&右值

看能不能对表达式取地址,如果能,则为左值,否则为右值

非常量左值引用和&常量左值引用

非常量左值引用只能绑定到【非常量左值】,不能绑定到常量左值、非常量右值和常量右值。

常量左值引用可以绑定到【所有类型的值】,包括非常量左值、常量左值、非常量右值和常量右值。

右值引用举例

vector<vector<int>> vec;
vector<int> vec2(10, 0);
vec.push_back(std::move(vec2)); // 类似一种浅拷贝机制,资源的所有权进行了转移,而不是复制

cout << vec2.size() << endl; // 运行时 core dump
class CMyString {
public:
// 构造函数
 CMyString(const char *pszSrc) { /* */ }

// 拷贝构造函数, 深拷贝
 CMyString(const CMyString &s) {
  m_pData = new char[strlen(s.m_pData)+1];
  strcpy(m_pData, s.m_pData);
 }

// move构造函数, 浅拷贝
 CMyString(CMyString &&s) {
  m_pData = s.m_pData;
  s.m_pData = NULL;
 }
private:
 char *m_pData;
};

std::move

C++11的std::unique_ptr 将 复制构造函数(参数为 const T& obj)和赋值操作符设为private且没有实现。
因此, 如下代码编译错误:

    unique_ptr<int> ptr(new int(1));
    unique_ptr<int> ptr2(ptr); //compile error
    
    or:
    unique_ptr<int> ptr2;
    ptr2 = ptr; // compile error
    
但 std::unique_ptr 定义了一个特殊的复制构造函数(参数为 T&& obj), 右值引用形参

    unique_ptr<int> ptr(new int(1));
    unique_ptr<int> ptr2(std::move(ptr)); // ok 
std::move基本等同于一个类型转换:
    static_cast<T&&>(lvalue);

参考

返回右值引用

The C++ Standard Library 2th edition --- Page 23:Note also that returning an rvalue reference is an error if the returned object is a local nonstatic object:
X&& foo ()
{
    X x;
    ...
    return x; // ERROR: returns reference to nonexisting object
}
An rvalue reference is a reference, and returning it while referring to a local object
means that you return a reference to an object that doesn’t exist any more. 
Whether std::move() is used doesn’t matter.

To Add Up

【参考4 MORE IMPORTANT】

1. 假如你想对象能够被移动,不要声明对象为const,在const对象上的移动操作默默的被转换成了拷贝操作。
2. std::move不仅不移动任何东西,甚至不能保证被转换的对象可以被移动。
   唯一可以确认的是应用std::move的对象结果是个右值。

完美转发

void processValue(int& a){ cout << "lvalue" << endl; }
void processValue(int&& a){ cout << "rvalue" << endl; }
template <typename T>
void forwardValue(T&& val)
{
    processValue(std::forward<T>(val)); 
}
void Testdelcl()
{
    int i = 0;
    forwardValue(i); //传入左值 
    forwardValue(0);//传入右值 
}

shiyang6017
158 声望59 粉丝

引用和评论

0 条评论