可能重复:
Should I return const objects?
(该问题的原始标题是: int foo()或const int foo()?解释我错过它的原因。)
有效的C ++,第3项:尽可能使用const。特别是,提升返回const对象以避免意外分配,如if (a*b = c) {
。我发现它有点偏执,但我一直在遵循这个建议。
在我看来,返回const对象会降低C ++ 11中的性能。
#include <iostream>
using namespace std;
class C {
public:
C() : v(nullptr) { }
C& operator=(const C& other) {
cout << "copy" << endl;
// copy contents of v[]
return *this;
}
C& operator=(C&& other) {
cout << "move" << endl;
v = other.v, other.v = nullptr;
return *this;
}
private:
int* v;
};
const C const_is_returned() { return C(); }
C nonconst_is_returned() { return C(); }
int main(int argc, char* argv[]) {
C c;
c = const_is_returned();
c = nonconst_is_returned();
return 0;
}
打印:
copy
move
我是否正确实施了移动分配?或者我只是不应该在C ++ 11中返回const对象?
答案 0 :(得分:25)
返回 const 对象是一种可能导致其他问题的解决方法。从C ++ 11开始,对于成员函数的赋值问题:参考限定符,有一个更好的解决方案。我尝试用一些代码来解释它:
int foo(); // function declaration
foo() = 42; // ERROR
第二行中的赋值导致C和C ++中内置类型int
的编译时错误。其他内置类型也是如此。那是因为内置类型的赋值运算符需要左侧的非const左值引用。要将它放在代码中,赋值运算符可能如下所示(无效代码):
int& operator=(int& lhs, const int& rhs);
在C ++中始终可以将参数限制为左值引用。但是,在C ++ 11之前,对于成员函数的隐式第一个参数(*this
),这是不可能的。
使用C ++ 11改变了:类似于成员函数的 const限定符,现在有成员函数的引用限定符。以下代码显示了复制和移动运算符的用法(请注意参数列表后面的&
):
struct Int
{
Int(const Int& rhs) = default;
Int(Int&& rhs) noexcept = default;
~Int() noexcept = default;
auto operator=(const Int& rhs) & -> Int& = default;
auto operator=(Int&& rhs) & noexcept -> Int& = default;
};
使用此类声明时,以下代码片段中的赋值表达式无效,而赋值给局部变量则起作用 - 就像在第一个示例中那样。
Int bar();
Int baz();
bar() = baz(); // ERROR: no viable overloaded '='
因此不需要返回const对象。您可以将赋值运算符限制为左值引用,以便其他所有内容仍然按预期工作 - 特别是移动操作。
另见:
答案 1 :(得分:22)
即使在C ++ 11之前,按值返回const
对象可能也不是一个好主意。它唯一的作用是它阻止调用者在返回的对象上调用非const函数 - 但这并不是非常相关,因为调用者无论如何都收到了对象的副本。
虽然返回一个常量对象确实会阻止调用者错误地使用它(例如错误地进行赋值而不是比较),但是函数决定调用者如何使用它不应该是函数的责任。返回的对象(除非返回的对象是函数所拥有的结构的引用或指针)。 函数实现者不可能知道返回的对象是用于比较还是其他用途。
你也是对的,在C ++ 11中问题甚至更严重,因为返回const
有效地阻止了移动操作。 (但它并不妨碍复制/移动省略。)
当然,当函数返回引用或指针时,同样重要的是指出const
仍然非常有用(并且使用它没有偏执的迹象)。
答案 2 :(得分:3)
您致const_is_returned
致copy constructor
而不是move constructor
的原因是move
必须修改对象,因此无法在{{{}}上使用const
1}}对象。我倾向于说在任何情况下都不建议使用const
并且应该接受程序员的判断,否则你得到你所展示的东西。好问题。