本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm

引言

众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalue reference ,右值引用。
引入它的一个非常重要的原因是因为在 C++ 中,常常右值,通俗地讲"在等号右边的"临时变量或者临时对象,我们是无法得到它的修改权限的。

由于类的构造和析构机制,往往产生的临时变量或临时对象的拷贝构造及析构,会带来不少的时间、资源消耗。
也同样由于这样的限制,有不少 C++ 程序员依然保有一部分 C 风格的写法,例如将 A = factory(B, C); 之中的A,以函数引用参数的形式传入等等。但在 C++11 之后,我们可以完全保留 C++ 的写法,将右值明显指出,就可以完成 "直接获得临时对象" 的资源的权限,例如 A = std::move(B); 或者 A = factory(B, C); ,这时候就 "几乎完全" 省去了拷贝的过程,通过直接获取由 factory(B, C); 造出的临时对象中的资源,达到省略拷贝的过程,最终析构的临时对象,实际上只是一具空空的皮囊。

 

以下有一个简单的右值引用的例子:(注,本文中的例子仅仅只是例子,请大家不要使用这种风格)

/**
 * Please use g++ -std=c++0x or g++ -std=c++11 to compile.
 */
#include <iostream>
#include <string>
#include <cstring>
 
template <typename T, std::size_t Num>
class Array
{
public:
    T * _M_data;
 
    Array() :
        _M_data(new T[Num])
    {}  // default constructor
 
    Array(const Array & rhs) :
        _M_data(new T[Num])
    {
        std::cout << "Copy Constructor." << std::endl;
        memcpy(_M_data, rhs._M_data, sizeof(T)*Num);
    }  // copy constructor
 
    // Move constructor -- from rvalue
    Array(Array && rhs) :
        _M_data(rhs._M_data)
    {
        std::cout << "Move Constructor." << std::endl;
        rhs._M_data = nullptr;
    }  // move constructor
 
    Array & operator=(const Array & rhs) {
        std::cout << "Copy Assignment." << std::endl;
        if (this == &rhs)
            return (*this);
        memcpy(_M_data, rhs._M_data, sizeof(T)*Num);
        return (*this);
    }  // copy assignment
 
    // Move Assignment -- from rvalue
    Array & operator=(Array && rhs) {
        std::cout << "Move Assignment." << std::endl;
        if (this == &rhs)
            return (*this);
 
        _M_data = rhs._M_data;
        rhs._M_data = nullptr;
        return (*this);
    }  // move assignment
 
    ~Array()
    {
        std::cout << "destructor." << std::endl;
        delete[] _M_data;
    }  // destructor
 
    static Array factory(const T & __default_val) {
        Array __ret;
        for (auto __i = 0ul; __i < Num; ++__i)
            __ret._M_data[__i] = __default_val;
        return __ret;
    }  // factor(defalt_value)
 
    void print(const std::string & __info) const {
        std::cout << __info;
        if (_M_data == nullptr) {
            std::cout << "_M_data is nullptr." << std::endl;
            return;
        }
 
        for(auto __i = 0ul; __i < Num; ++__i)
            std::cout << _M_data[__i] << ' ';
        std::cout << std::endl;
    }
};
 
int main()
{
    const std::size_t NUM = 10ul;
 
    Array<int, NUM> a0;
    for (auto __i = 0ul; __i < NUM; ++__i)
        a0._M_data[__i] = __i;
    a0.print("a0: ");
 
    Array<int, NUM> a1(a0);
    a0.print("a0: ");
    a1.print("a1: ");
 
    Array<int, NUM> a2(std::move(a1));
    a1.print("a1: ");
    a2.print("a2: ");
 
    Array<int, NUM> a3;
    a3.print("a3(uninitialized): ");
    a3 = a2;
    a3.print("a3: ");
    a3 = Array<int, NUM>::factory(1024);
    a3.print("a3: ");
 
    std::cout << "----------" << std::endl;
    return 0;
}
View Code

相关文章:

  • 2021-05-24
  • 2021-10-15
  • 2021-08-05
  • 2022-12-23
  • 2021-12-03
  • 2022-12-23
  • 2021-12-26
  • 2021-05-30
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-23
  • 2021-06-17
  • 2021-10-05
  • 2021-07-12
相关资源
相似解决方案