1.临时对象作为右值引用减少拷贝构造
  前面一些文章https://blog.nowcoder.net/detail/91bd120053d749448e8fabfd6b6db645 可能会疑惑,这个右值我不用也可以啊,为什么偏偏要发明这个东西,如果以下代码:

#include <iostream>
#include <memory>
#include <string>
using namespace std;
int g_constructNum = 0;
int g_copyConstructNum = 0;
int g_moveConstructNum = 0;
int g_deleteNum = 0;

class MyTestString
{
private:
    std::string m_data;
    int m_value;
    void test() {}
public:
    MyTestString(std::string data,int value) :m_data(data),m_value(value)
    {
        std::cout << "construct: " << ++g_constructNum << std::endl;
    }
    MyTestString(const MyTestString& myTestString)
    {
        m_data = myTestString.m_data;
        m_value = myTestString.m_value;
        std::cout << "copy construct: " << ++g_copyConstructNum << std::endl;
    }
    ~MyTestString()
    {
        std::cout << "destruct: " << ++g_deleteNum << std::endl;
    }
};

MyTestString getTempString()
{
    MyTestString temp("tangmiao", 1);
    return temp;
}

int main()
{
    MyTestString temp(getTempString());
    return 0;
}

如果编译器没有优化的话,那么结果应该是这个样子:
图片说明
函数返回做一次拷贝构造,主函数里做一次拷贝构造。如果编译器做返回值优化,那么可能没有copy construct或者少。一些复杂的情况并也不是编译器能够优化的。这么多次拷贝构造又要***,又要删除临时对象,很浪费时间和空间。使用右值引用的话,就会延长临时对象的生命周期,并且采用移动构造函数,利用std::swap()来交换内存空间,而不是删除和新增,会减少很多开销。代码如下:

#include <iostream>
#include <memory>
#include <string>
using namespace std;
int g_constructNum = 0;
int g_copyConstructNum = 0;
int g_moveConstructNum = 0;
int g_deleteNum = 0;

class MyTestString
{
private:
    std::string m_data;
    int m_value;
    void test() {}
public:
    MyTestString(std::string data,int value) :m_data(data),m_value(value)
    {
        std::cout << "construct: " << ++g_constructNum << std::endl;
    }
    MyTestString(const MyTestString& myTestString)
    {
        m_data = myTestString.m_data;
        m_value = myTestString.m_value;
        std::cout << "copy construct: " << ++g_copyConstructNum << std::endl;
    }
    MyTestString(MyTestString &&myTestString)
    {
        std::swap(m_data, myTestString.m_data);
        std::swap(m_value, myTestString.m_value);
        std::cout << "move copy construct: " << ++g_moveConstructNum << std::endl;
    }
    ~MyTestString()
    {
        std::cout << "destruct: " << ++g_deleteNum << std::endl;
    }
};

MyTestString getTempString()
{
    MyTestString temp("tangmiao", 1);
    return temp;
}

int main()
{
    MyTestString temp(getTempString());
    return 0;
}

输出应为:
图片说明
类似的std::vector库的右值引用用处:(来自如何评价 C++11 的右值引用(Rvalue reference)特性? - Tinro的回答 - 知乎
https://www.zhihu.com/question/22111546/answer/30801982
图片说明

2.使用std::move直接将左值转化为右值
move是将对象的状态或者所有权直接从一个对象转移到另外一个对象,只是转移,没有内存拷贝,不会消耗太多资源。如下:

std::list<std::string> test;
...
std::list<std::string> t=test;

将test东西完全拷贝到t里,性能较低。如下性能会提高很多:

std::list<std::string> test;
...
std::list<std::string> t=std::move(test);

使用move几乎没有任何代价,只是转换了资源的所有权,实际上是将左值变成了右值引用,然后应用move语义调用构造函数,避免了拷贝,提高了程序的性能。当一个对象内部有较大的堆内存或者动态数组时,很有必要写move语义的拷贝构造函数和赋值函数(移动构造函数和移动赋值函数),避免无意义的深拷贝,提高性能。在C++STL库里很多地方都使用了move语义去提高性能。