移动语义和常量引用

Move semantics and const references

本文关键字:引用 常量 语义 移动      更新时间:2023-10-16

我花了很多时间为我的类实现移动语义,但现在我正在处理使用它的函数。

好的,我有一个对象,它在堆上有很多数据:CLargeOb,我为它实现了移动语义(构造函数和运算符=)。它的理想用途是:

void OtherOb::Func(CLargeOb&& largeOb1, CLargeOb&& largeOb2)
{
    SomeOtherFunc(largeOb1); // use objects
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1; // save as members and trash the originals
    m_largeOb2 = (CLargeOb&&)largeOb2;
}

然而,并不总是可以允许对象被移动/丢弃,所以我添加了以下两个功能:

void OtherOb::Func(const CLargeOb& largeOb1, CLargeOb&& largeOb2)
{
    SomeOtherFunc(largeOb1);
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = largeOb1;
    m_largeOb2 = (CLargeOb&&)largeOb2;
}
void OtherOb::Func(CLargeOb&& largeOb1, const CLargeOb& largeOb2)
{
    SomeOtherFunc(largeOb1);
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1;
    m_largeOb2 = largeOb2;
}

虽然它有效,但你已经可以猜到,当我有一个函数将其中3个或更多的对象作为参数时,它将成为*ss中的一个主要问题。。。难道没有一种聪明的方法可以使用模板或"完美转发"来解决这个问题吗?

与C++03中的情况一样,准则是:如果您想要一个副本,请在参数列表中创建它

这让调用者处理你如何获得对象,你只需要获得一个对象,不管:

void OtherOb::Func(CLargeOb largeOb1, CLargeOb largeOb2) 
{ 
    SomeOtherFunc(largeOb1); // use objects 
    SomeOtherFunc(largeOb2);  
    m_largeOb1 = std::move(largeOb1); // save as members and trash the originals 
    m_largeOb2 = std::move(largeOb2); // (you should use std::move, not cast)
} 

来电者:

OtherOb o;
CLargeOb x, y;
const CLargeOb z;
o.Func(x, std::move(y)); // need x for later, done with y so move it
o.Func(std::move(x), z); // done with x, necessarily copy z

这和几个专门的重载一样有效。为什么因为这些已经作为构造函数存在于类中。让编译器为您确定在调用站点调用哪个,它已经知道该做什么了。