我是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;
}
它正确编译和执行,但我不确定,这是否是正确可行的工作方式?
这种操作是否有一些最佳实践?
答案 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()函数。它会有相同的行为。