【问题标题】:why sometime a function return a const, or const reference为什么有时一个函数会返回一个 const 或 const 引用
【发布时间】:2011-05-20 04:17:08
【问题描述】:

首先,为什么要返回 const? 说我有

friend const MyVec operator-(const MyVec& left, const MyVec& right)

所以返回 const 让我做不到:

mva - mvb = mvc;

第二,为什么要返回 const 引用? 如果有:

friend const MyVec& operator++(MyVec& v)

使用 const 我不能:(++mva) = mvc

如果是的话

MyVec& operator++(MyVec& v)

我可以:++(++mva) // 增加两次。

我理解对了吗?

【问题讨论】:

    标签: c++ operator-overloading constants


    【解决方案1】:

    没有任何好的理由返回一个 const 对象。但是,返回指向 const 对象的指针或引用有很多很好的理由。

    程序可能有一个复制成本很高的对象,因此它返回一个引用。但是,不应通过该引用更改对象。例如,它可能是已排序数据结构的一部分,如果它的值被修改,它将不再被正确排序。所以 const 可以防止它被意外修改。

    算术运算符函数不应返回 const 对象,因为正是您的问题中的问题。

    取消对迭代器的引用应该返回一个 const 引用。也就是说,如果它正在对 const 对象的集合或可能对 const 集合进行操作。这就是为什么类函数有时有一个函数的两个副本,第二个副本在函数本身上使用 const,如下所示:

    T& operator[](size_t index);
    const T& operator[](size_t index) const;
    

    第一个函数用于非 const 对象,第二个函数用于 const 对象。

    【讨论】:

    • "有时在迭代器上使用的 operator++ 应该返回一个 const 引用" 不,它不应该。因为每个人都希望++(++obj) 表达式有效。定义前缀 ++ 运算符最有用的方法是T& T::operator++() {...},没有充分的理由定义它。可能你打错了什么?可能你的意思是operator[],就像你的例子一样?
    • "没有任何充分的理由返回一个 const 对象" 是的,有,参见 Effective C++ item 21. 防止像 (a * b) = c 这样的构造
    • “算术运算符函数不应返回 const 对象”:假设您的意思是 - 和 + 等。是的,它们应该:参见 Effective C++ 和 cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
    • @rve : 'Effective C++' 虽然总体上很优秀,但早于 C++11;如果现在发布新版本,我保证会删除该建议,因为它禁用了 C++11 中的自动移动语义。因此,换种说法:在现代 C++ 中,没有任何充分的理由返回一个 const 对象。
    • @ChristianRau: if((a*b)==c) vs if((a*b)=c) - 不是不知道不做,而是不做错。
    【解决方案2】:

    是的,您的理解是正确的。 为避免意外分配,可以通过constconst reference 返回一个对象。

    使用operator -,您可以按值返回一个对象。为避免被意外编辑,可以通过const 值返回,因为无论如何该对象将主要是临时对象。

    对于operator ++,通常它返回引用,但是为避免出现(++ x) = y; 的情况,您可以通过const 引用返回它。

    【讨论】:

    • 在使用 C++11 编译器进行编译时,返回 const 值会使自动移动语义变得不可能;这真的只是糟糕的建议。
    • @ildjarn,可能是。但我没有建议:)。这是他所问的答案。提问者没有使用 C++11,或者知道这些含义。
    • 哦,我并不是要暗示您建议返回 const 值;我只是想说,在 C++11 出现时,这通常是个坏建议。 :-]
    猜你喜欢
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    相关资源
    最近更新 更多