C++右值引用与移动构造

目录

将亡值

右值引用

移动构造

综合代码

将亡值

        在栈上只调用类中构造函数的对象叫做临时对象,这个对象只有空间在栈上而没有地址,临时对象没有地址,所以他的生命周期非常短暂,在发生传递之后就被销毁了。

        类型 a = 类型中的构造函数() //这种形式就是使用一个临时对象为本对象进行初始化。

        比如:A a = A();

右值引用

右值引用的语法:
类型&& 变量 = 临时变量(常量)

        1.右值引用只能引用右值,不能引用左值

        2.当父类的右值引用引用了一个子类的临时对象,也是可以发生多态的

        3.使用右值引用可以避免const修饰的左值引用的必须在类中成员函数后加const的问题,而无需修改源码。

移动构造

类名(类型&& other)
{
    this->资源 = other.资源
    other.资源 = nullptr;
}

        将自身资源赋值给别人后,自身指向nullptr。

综合代码

        定义一个父类:

#include <iostream>
using namespace std;
class A
{
public:
    A()
    {
        cout << "A的构造" << endl;
    }
    A(const A& other)
    {
        cout << "A的拷贝构造" << endl;
    }
    A(A&& other)
    {
        cout << "A的移动构造" << endl;
    }
    virtual ~A()
    {
        cout << "A的析构 " << endl;
    }
    virtual void showInfo()
    {
        cout << "同学们加油哦" <<endl;
    }
};

        定义一个子类:

class B : public A
{
private:
    int *p;
public:
    B() : p(new int [1024])
    {
        cout << "B的构造: " << endl;
    }
    ~B()
    {
        if(p != nullptr)
        {
            delete []p;
        }
        cout << "B的析构" << endl;
    }
    B(const B& other)
    {
        this->p = new int [1024];
        memcpy(this->p, other.p, sizeof (int [1024]));
        cout << "B的拷贝构造" << endl;
    }
    B(B&& other)
    {
        this->p = other.p;
        other.p = nullptr;
        cout << "B的移动构造" << endl;
    }
    void showInfo() override
    {
        cout << "同学加油 " << endl;
    }
};

        主函数验证:

int main()
{
// //正常使用
// A * a = new B();
// a->showInfo();
// delete a;
cout << "-----------------------------------------------------------" << endl;

    //这里的B()是将亡值
// A a = B();
// a.showInfo();
// A& a1 = B(); //报错,将亡值,也叫临时对象,这种临时对象也被称为右值,不能引用右值
cout << "-----------------------------------------------------------" << endl;

    //解决方法1:
// const A& a1 = B();
// a1.showInfo();
// //更改父类为常函数 void showInfo() const
// //更改子类为常函数 void showInfo() const override
// 本质是:B temp = B(); const A& a1 = temp;
cout << "-----------------------------------------------------------" << endl;

   //解决方法2:
    //const A& a1 = B();
    //const_cast<A&>(a1).showInfo(); //使用强转
cout << "-----------------------------------------------------------" << endl;

    //解决方式3: 右值引用
    //从const修饰的左值引用,升级为右值引用,右值引用可以锁定将亡值
    //A&& a2 = B();
    //a2.showInfo();
cout << "-----------------------------------------------------------" << endl;

    //方法4: 移动构造
    //B a1 = B();
    //B&& a3 = std::move(a1);
    //使用移动语义函数 std::move(左值), 此方法,会将原对象的空间直接给新对象用,即新旧指向同一片空间
    //a3.showInfo();
    //a1.showInfo();
    //cout << &a3 << endl; //0x61fdf0
    //cout << &a1 << endl; //0x61fdf0

     return 0;
}

        运行结果:

        读者可复制代码,逐个解注释,查看运行效果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值