我还应该在 C++11 中返回 const 对象吗?
可能重复:
我应该返回 const 对象吗?
(该问题的原标题是:int foo() 还是 const int foo()? 解释了我为什么错过它.)
Possible Duplicate:
Should I return const objects?
(The original title of that question was: int foo() or const int foo()? explaining why I missed it.)
<小时>
Effective C++,第 3 条:尽可能使用 const.特别是,返回 const 对象被提升以避免像 if (a*b = c) {
这样的意外赋值.我觉得这有点偏执,但我一直遵循这个建议.
Effective C++, Item 3: Use const whenever possible. In particular, returning const objects is promoted to avoid unintended assignment like if (a*b = c) {
. I find it a little paranoid, nevertheless I have been following this advice.
在我看来,返回 const 对象会降低 C++11 的性能.
It seems to me that returning const objects can degrade performance in 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 对象?
Do I implement the move assignment correctly? Or I simply shouldn't return const objects anymore in C++11?
推荐答案
返回 const 对象是一种可能导致其他问题的解决方法.从 C++11 开始,赋值问题有了更好的解决方案:Reference Qualifiers 用于成员函数.我尝试用一??些代码来解释它:
Returning const objects is a workaround that might cause other problems. Since C++11, there is a better solution for the assignment issue: Reference Qualifiers for member functions. I try to explain it with some code:
int foo(); // function declaration
foo() = 42; // ERROR
第二行中的赋值导致 C 和 C++ 中内置类型 int
的编译时错误.其他内置类型也一样.这是因为内置类型的赋值运算符需要左侧的非常量左值引用.把它放在代码中,赋值运算符可能如下所示(无效代码):
The assignment in the second line results in a compile-time error for the builtin type int
in both C and C++. Same for other builtin types. That's because the assignment operator for builtin types requires a non-const lvalue-reference on the left hand side. To put it in code, the assignment operator might look as follows (invalid code):
int& operator=(int& lhs, const int& rhs);
在 C++ 中总是可以将参数限制为左值引用.但是,在 C++11 之前,对于成员函数的隐式第一个参数 (*this
),这是不可能的.
It was always possible in C++ to restrict parameters to lvalue references. However, that wasn't possible until C++11 for the implicit first parameter of member functions (*this
).
这在 C++11 中发生了变化:类似于成员函数的 const 限定符,现在有成员函数的引用限定符.以下代码展示了复制和移动操作符的用法(注意参数列表后面的&
):
That changed with C++11: Similar to const qualifiers for member functions, there are now reference qualifiers for member functions. The following code shows the usage on the copy and move operators (note the &
after the parameter list):
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;
};
使用此类声明,以下代码片段中的赋值表达式无效,而赋值给局部变量有效 - 就像在第一个示例中一样.
With this class declaration, the assignment expression in the following code fragment is invalid, whereas assigning to a local variable works - as it was in the first example.
Int bar();
Int baz();
bar() = baz(); // ERROR: no viable overloaded '='
所以没有必要返回 const 对象.您可以将赋值运算符限制为左值引用,以便其他一切仍按预期工作 - 特别是移动操作.
So there is no need to return const objects. You can restrict the assigment operators to lvalue references, so that everything else still works as expected - in particular move operations.
另见:
- 什么是*this"的右值引用?一个>
相关文章