为什么const方法不能返回非const引用?

时间:2014-06-21 22:50:56

标签: c++ c++11 reference const const-cast

为什么赢得以下编译方法getRanks(),如何正常修复它?

我想做的就是定义一个成员访问器方法,该方法返回对成员的引用。引用不是const,因为我可能会修改它后面引用的内容。但由于成员方法不修改对象,我将其声明为const。编译器(clang,std = c ++ 11)然后坚持认为存在"引用的绑定" "掉落资格赛"。但我不会放弃预选赛,是吗?如果我是,为什么:

struct teststruct{
  vector<int> ranks;
  vector<int>& getRanks()const{
    return ranks;
  }
};

现在,如果我更改return语句以抛弃const:

,代码就会编译
return const_cast<vector<int>&>(ranks);

但&#34;排名&#34;首先不应该是const,我不明白为什么我需要const_cast the const。我甚至不知道这样做是否安全。

无论如何,这个方法有没有更清洁?有人可以解释为什么这种简单的常识方法失败了吗?我想宣布getRanks()方法&#34; const&#34;这样我就可以用其他const方法调用它。

4 个答案:

答案 0 :(得分:7)

const成员函数背后的想法是你应该能够在const个对象上调用它们。 const函数无法修改对象。

假设你有一个班级

class A
{
   int data;
   void foo() const
   {
   }
};

以及对象和函数调用:

A const a;
a.foo();

A::foo内,this->data被视为其类型为int const,而不是int。因此,您无法修改this->data中的A:foo()

以您的示例为例,this->ranks中的getRanks()类型被视为const vector<int>而不是vector<int>。因为,不允许将const vector<int>自动转换为vector<int>&,所以当您将函数定义为:

时,编译器会抱怨
vector<int>& getRanks()const{
    return ranks;
  }

如果将函数定义为:

,则不会抱怨
const vector<int>& getRanks()const{
    return ranks;
  }

因为const vector<int>可以自动转换为const vector<int>&

答案 1 :(得分:4)

ranksconst,因为封闭对象(*this)为const,因此您必须返回对std::vector<int> const的引用。

如果要允许客户端修改向量(从而影响成员),则getter不应为const。请注意,无论如何,getter都是愚蠢的,因为ranks已经是公共数据成员。

答案 2 :(得分:1)

您将返回ranks的引用,teststructteststruct的成员。这意味着任何获得此引用的人都可以修改const对象的内部。所以const是谎言。

不要抛弃const。相反,决定您是希望函数为ranks并返回constconst引用的副本,还是非{{1}}并返回可变引用。如果需要,你可以随时都有。

答案 3 :(得分:0)

它会删除限定符,因为您返回对ranks的引用。之后的任何代码都可以修改排名例如:

auto v = teststruct.getRanks();
v[1] = 5; //assuming v.size() > 1

您可以通过返回副本来解决此问题:

vector<int> getRanks() const

const参考:

const vector<int>& getRanks() const

如果您希望即使在ranks对象中const可以变换,也可以这样做:

mutable vector<int> ranks;