none
C++0X-右值引用 RRS feed

  • 常规讨论

  • 简介

    C++0X是新一代C++标准的非官方名称。它将代替C++03成为C++最新的标准。C++0XC++的核心语言以及标准库经进行了部分更新。C++0X完全兼容目前的C++标准。

    C++0X之中,语言本身添加了对于多线程的支持。一些细节得到了改进,例如支持统一初始化方式。对泛型编程的支持方面有了更边界的,同时对功能进行了改进。

    核心语言功能

    右值引用

    C++03中,临时变量(右值,出现在等号右侧的变量。另一种解释是引用值,没有实际地址的值)和const & type没有实际的差别。而在C++0X标准中添加了一种新的引用类型。叫做右值引用。它的定义类似于typename &&。另外右值引用提供了一种转移语义。

    动机

    右值引用的出现使得一些基础概念或者effective C++中表述的一些条目需要重新编写。那么来看看右值引用出现的动机是什么。

    来看一个例子

    std::vector实际上内部就是一个C类型数组,并且提供了一些内存和性能优化管理的机制。那么在现行的C++03标准中,当一个vector临时变量或者函数返回一个vector类型对象的时候。这里无可避免、毫无疑问的将会产生一个新的vector变量,并且将所有右值中的成员变量拷贝到这个临时变量中。(当然有些编译器具有NRV的优化功能,但是这种优化功能的执行情况和在复杂函数中的优化效果值得商榷)并且在拷贝结束后这个临时变量将被销毁,完成它短暂而又神圣的使命。

    vector<SpecialClass> func()

    {

                 

                    return vect;

    }

    使用右值引用,在以上场景中std::vector的转移构造函数会被调用。转移的过程是把右值vector中指向C类型数组的指针直接拷贝到新的vector对象中。然后把右值中的数组指针置空。这样就省去了数组拷贝过程,并且删除一个空的临时变量不会产生大量的内存操作。

    那么我们需要将返回值声明为std::vector<>&&,将会大幅简化内存操作。

    vector<SpecialClass>&& func()

    {

                 

                    return std::move(vect);

    }

     

    右值引用不能引用一个左值对象,为了可以对指定的左值对象进行右值引用操作。标准库提供了std::move()函数。通过该函数可以获得指定对象的左值。

    为自己的类定制右值引用构造函数

    SpecialClass(SpecialClass&& rhs)

    {

    return *this;

    }

    当调用右值引用的类并没有定义右值引用构造函数时,默认的拷贝构造函数会被调用,并且参数会以const &的形式传入。

    为了便于在模板中进行参数推到,标准库提供了std::forward()函数通过此函数可以保证传入参数的左右值性质不变

    template <class T, class A1>

    inline

    shared_ptr<T>

    factory(A1&& a1)

    {

        // If a1 is bound to an lvalue, it is forwarded as an lvalue

        // If a1 is bound to an rvalue, it is forwarded as an rvalue

        return shared_ptr<T>(new T(forward<A1>(a1)));

    }

     

    struct A

    {

        ...

        A(const A&);  // lvalues are copied from

        A(A&&);       // rvalues are moved from

    };

     

    int main()

    {

        A a;

        shared_ptr<A> sp1 = factory<A, A>(a);        // "a" copied from

        shared_ptr<A> sp2 = factory<A, A>(move(a));  // "a" moved from

    }


    麻烦把正确答案设为解答。
    2009年6月10日 0:45
    版主