我应该仍然在C ++ 11中返回const对象? [英] Should I still return const objects in C++11?

查看:103
本文介绍了我应该仍然在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.)






有效的C ++,第3项: 。特别是,如果(a * b = c){,则促进返回const对象以避免非预期的赋值。我发现它有点偏执,但是我一直遵循这个建议。


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为赋值问题参考限定符提供了更好的解决方案。我尝试用一​​些代码解释它:

Returning const objects is a workaround, that causes a lot of other problems. C++11 provides 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

赋值表达式无效,正如你所看到的, 。仍然没有什么特别的事情发生在这里。想一下内置赋值运算符如下。显然,上述赋值表达式无效,而使用命名变量的赋值操作起作用。

The assignment expression is invalid, and as you can see, there are no const objects involved. Still nothing special is happening here. Think of the builtin assignment operator as follows. It is clear, that the above assignment expression is invalid whereas the assignment with a named variable works.

int& builtin_assign_int(int& lhs, const int& rhs);

因此可以将参数限制为左值引用。但是,不可能将成员函数( * this )的隐式第一个参数限制为lvalue引用。

So it is possible to restrict parameters to lvalue references. However, it is not possible to restrict the implicit first parameter of member functions (*this) to lvalue references.

用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.

另请参阅:

  • What is "rvalue reference for *this"?

这篇关于我应该仍然在C ++ 11中返回const对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆