4

为什么下面的方法不能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);

但是“排名”首先不应该是 const ,我不明白为什么我需要 const_cast const 。我什至不知道这样做是否安全。

无论如何,有没有更清洁的人来写这个方法?有人可以解释为什么这种简单的常识方法会失败吗?我确实想声明getRanks()方法“ const”,以便我可以从其他const方法调用它。

4

4 回答 4

7

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

假设你有一堂课

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

在对象和函数调用上:

A const a;
a.foo();

在里面A::foothis->data被当作它的类型是int const,不是int。因此,您无法this->dataA:foo().

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

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

如果您将函数定义为:

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

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

于 2014-06-21T23:06:07.887 回答
4

ranksconst因为封闭对象 ( *this) 是const,所以你必须返回对 a 的引用std::vector<int> const

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

于 2014-06-21T22:55:46.553 回答
1

您正在返回对 的引用ranks,它是 的成员teststruct。这意味着任何获得此引用的人都可以修改teststruct对象的内部结构。所以这const是一个谎言。

不要抛弃const. 取而代之的是,决定您是否希望函数成为const并返回一个副本ranksconst引用,或者是非const并返回一个可变引用。如有必要,您始终可以同时拥有两者。

于 2014-06-21T22:53:38.610 回答
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;
于 2014-06-21T22:54:22.867 回答