【问题标题】:Returning a reference from a constant function从常量函数返回引用
【发布时间】:2009-01-29 04:36:17
【问题描述】:
#include "iostream"
#include "vector"

class ABC {

};

class VecTest {

  std::vector<ABC> vec;

  public:

  std::vector<ABC> & getVec() const { //Here it errors out
      return vec;
  }

};

删除 const 修复它,不是 getVec 是一个常量方法吗?那么为什么不允许这样做呢?

【问题讨论】:

    标签: c++ methods constants


    【解决方案1】:

    您可能应该做的是返回一个 const 引用。

    const std::vector& getVec() const { return vec; }

    这是不允许的,因为您说过 getVec 是一个 const 方法,这意味着该方法不应以任何方式更改 this 对象。返回非常量引用可能会允许其对象被更改,因此编译器不允许这样做。

    【讨论】:

      【解决方案2】:

      如果一个方法是 const 则它向编译器保证,对象的状态不能通过调用该方法来改变。

      如果方法返回对内部成员的引用,那么方法的用户可以通过引用间接改变对象的状态。

      所以实际上 const 方法不能返回引用(因为它允许间接更改对象的状态)。您可以做的是返回一个 const 引用。从而允许用户访问内部成员但维护成本合约。

      例子:

      class X
      {
          int&       getX();       // get a reference to X
          int const& getX() const; // get a reference to X BUT the interface guarantees
                                   // the object will not change state.
          private:
              int x;
      }; 
      

      另一种看待它的方式。
      如果你有一个 const 对象。 允许您调用 const 方法。如果通过调用 const 方法可以检索对对象内部成员的引用,则可以更改其状态。这将违反原始对象的 const(ness)。

      【讨论】:

        【解决方案3】:

        getVec()的返回类型需要为const std::vector&lt;ABC&gt;&amp;

        【讨论】:

          【解决方案4】:

          为了补充已经说过的内容,当你创建一个 const 方法时,它获得的对象实例(this 指针)本质上变成了 const。请记住,当您返回 vec 时,您会隐式返回 this-&gt;vec

          return this->vec; // it's a const std::vector<ABC> since "this" is const
          

          “Constness”不能被取消——除非你用const_cast&lt;&gt; 明确地取消它。

          // to illustrate what's happening when you're returning from the function
          std::vector<ABC> &return = this->vec; // can't assign const to non-const!
          

          因此,您的返回类型也必须是 const:

          const std::vector<ABC> &return = this->vec; // all is good
          

          【讨论】:

            【解决方案5】:

            补充一下Ray Hidayat 所说的,一个 const 方法只能对类成员进行 const 访问。您正在尝试返回对 const 成员变量的非 const 引用,因此它失败了。

            如果您确实需要从 const 函数访问成员变量的可修改版本,您可以将变量声明为可变。不过我不会推荐它。

            【讨论】:

              猜你喜欢
              • 2020-07-06
              • 2021-08-10
              • 2019-09-03
              • 1970-01-01
              • 1970-01-01
              • 2012-11-12
              • 1970-01-01
              相关资源
              最近更新 更多