zoukankan      html  css  js  c++  java
  • 移动构造函数

    左值(lvalue, left value),顾名思义就是赋值符号左边的值。准确来说, 左值是表达式(不一定是赋值表达式)后依然存在的持久对象。
    右值(rvalue, right value),右边的值,是指表达式结束后就不再存在的临时对象。
    C++11 中为了引入强大的右值引用,将右值的概念进行了进一步的划分,分为:纯右值和将亡值。
    纯右值 (prvalue, pure rvalue),纯粹的右值,要么是纯粹的字面量,例如 10, true; 要么是求值结果相当于字面量或匿名临时对象,例如 1+2。非引用返回的临时变量、运算表达式产生的临时变量、原始字面量、Lambda 表达式都属于纯右值。

    移动构造函数的作用

    #include <iostream>
    
    using namespace std;
    
    class Base
    {
    public:
        Base(void) { cout << __PRETTY_FUNCTION__ << ":" << this << endl; }
        Base(const Base &) { cout << __PRETTY_FUNCTION__ << ":" << this << endl; }
        Base(Base &&) { cout << __PRETTY_FUNCTION__ << ":" << this << endl; }
        // 上面两个 Base(const Base &) 与 Base(Base &&) 可用下面模板代替
        // template<typename T>
        // Base(T &&) { cout << __PRETTY_FUNCTION__ << ":" << this << endl; }
    
        Base &operator=(const Base &)
        {
            cout << __PRETTY_FUNCTION__ << ":" << this << endl;
            return *this;
        }
    
        ~Base() { cout << __PRETTY_FUNCTION__ << ":" << this << endl; }
    
    private:
    };
    
    Base func()
    {
        return Base();
    }
    
    int main(int argc, char **argv)
    {
        auto bb = func();
    
        return 0;
    }
    

    注意,目前多数编译器都会对程序中发生的拷贝操作进行优化,因此直接编译运行此程序时,看到的往往是优化后的输出结果:

    在 Linux 上使用 g++ demo.cpp -fno-elide-constructors,就可以看到完整的输出结果:

    可以看出函数 func 在没有优化时候流程是这样的:

    • 执行Base() 默认构造函数,构造一个临时的匿名对象
    • 拷贝匿名对象到返回值,并销毁匿名变量
    • 执行 bb = 返回值,也就是执行拷贝构造函数,然后销毁返回值
      这之间多次调用了构造函数。

    移动构造函数

          ...
        Base(Base &&) { cout << __PRETTY_FUNCTION__ << ":" << this << endl; }
          ...
    


    可以看出,添加移动构造函数后执行了移动构造函数Base::Base(Base&&)。减少了多次调用构造函数的开销。(移动语义与完美转发仅在编译阶段起作用,运行期间不执行任何代码)。

    移动语义与完美转发

    C++11朝码夕解: move和forward
    C++11 std::move和std::forward
    c++11 中的 move 与 forward
    [CPP] 左值 lvalue,右值 rvalue 和移动语义 std::move
    [c++11]我理解的右值引用、移动语义和完美转发

  • 相关阅读:
    [转]一致性hash算法
    [转]算法的时间复杂度和空间复杂度详解
    [转]B树(多向平衡查找树)详解
    spring中ApplicationContextAware接口描述
    [转]web.xml中<url-pattern>详解
    [转]linux中vim命令
    [转]Java GC的原理
    [转]浅谈UML的概念和模型之UML九种图
    Jmeter做读取csv接口测试
    IDLE崩溃:IDLE's subprocess didn't make connection. Either IDLE can't start a...
  • 原文地址:https://www.cnblogs.com/sinpo828/p/14172489.html
Copyright © 2011-2022 走看看