使用rvalue

时间:2015-06-28 11:11:01

标签: c++ c++11 reference

我是C ++ 11的新手。实际上直到最近,我才使用类似于Java的动态分配进行编程,例如

void some_function(A *a){
   a->changeInternalState();
}

A *a = new A();
some_function(a);
delete a;

// example 2
some_function( new A() ); // suppose there is **no** memory leak.

现在我想用C ++ 11重现类似的代码,但没有指针。

我需要能够将新创建的类class A直接传递给函数useA()。如果我想使用非const 正常引用来执行此操作似乎存在问题,并且如果我使用rvalue引用执行此操作则会有效。

以下是代码:

#include <stdio.h>

class A{
public:
        void print(){
                ++p; // e.g. change internal state
                printf("%d\n", p);
        }

        int p;
};

// normal reference
void useA(A & x){
        x.print();
}

// rvalue reference
void useA(A && x){
        useA(x);
}

int main(int argc, char** argv)
{
        useA( A{45} );   // <--- newly created class 

        A b{20};

        useA(b);

        return 0;
}

它正确编译和执行,但我不确定,这是否是正确可行的工作方式?

这种操作是否有一些最佳实践?

2 个答案:

答案 0 :(得分:2)

通常,您不会设计代码以便修改临时对象。然后你会把你的打印功能写成:

void useA(A const & x){
    x.print();
}

并将A::print声明为const。这与rvalues和lvalues都有关系。您可以将mutable用于类成员变量,这些变量可能会更改值,但对象不会在逻辑上改变状态。

另一个计划是保持A &,但写下:

{ A temp{45}; useA(temp); }

如果您确实想要修改临时对象,可以像在问题中一样编写一对左值和右值重载。我相信这种做法是可以接受的。

答案 1 :(得分:-1)

关于C ++ 11移动语义的最好的事情是,大部分时间,你得到它们&#34;免费&#34;无需在代码中明确添加任何&amp;&amp; s或std :: move()。通常,如果您正在编写执行手动内存管理的代码(例如智能指针或容器类的实现),您只需编写自定义析构函数和复制构造函数,就只需要明确地使用这些内容。反正。

在您的示例中,A只是一个int。对于整数,移动与副本没有什么不同,因为即使int恰好是一次性临时,也没有优化的机会。只需提供一个带有普通引用的useA()函数。它会有相同的行为。