返回一个向量成员变量的引用

55

我在一个类中有一个向量作为成员,我希望通过getVector()函数返回对它的引用,以便稍后能够修改它。函数getVector()是否最好是常量? 但是在下面的代码中,我遇到了错误“qualifiers dropped in binding reference of type…”. 应该做出什么修改?

class VectorHolder
{
public:
VectorHolder(const std::vector<int>&);
std::vector<int>& getVector() const;

private:
std::vector<int> myVector;

};

std::vector<int> &VectorHolder::getVector() const
{
return myVector;
}
4个回答

57

由于这是一个const成员函数,返回类型不能为非const引用。请将其改为const

const std::vector<int> &VectorHolder::getVector() const
{
   return myVector;
}

现在没问题了。

为什么现在没问题了呢?因为在一个const成员函数中,每个成员都变成const的,这样就无法修改了,这意味着在函数内myVector是一个const向量,所以如果返回引用类型的话,你必须使返回类型也是const。现在你不能修改同一个对象了。看看你能做什么,不能做什么:

 std::vector<int> & a = x.getVector();       //error - at compile time!

 const std::vector<int> & a = x.getVector(); //ok
 a.push_back(10);                            //error - at compile time!

 std::vector<int>  a = x.getVector();        //ok
 a.push_back(10);                            //ok

顺便问一下,我想知道你为什么需要这样的VectorHolder


那么这样就不可能从返回向量的代码中稍后修改它了? - arjacsoh

23

通常情况下会同时声明const和mutable变量,像这样:

it's not unusual to declare both const and mutable variants, like so:

std::vector<int>& VectorHolder::getVector() {
  return myVector;
}
const std::vector<int>& VectorHolder::getVector() const {
  return myVector;
}

你程序中的根本问题是在 const 方法中返回了一个非 const 引用。

std::vector<int>& VectorHolder::getVector() const {
  return myVector; // << error: return mutable reference from const method
}

所以,您可以使用以下形式将其声明为const:

const std::vector<int>& VectorHolder::getVector() const {
  return myVector; // << ok
}

如果这个方法不是 const 的,或者客户端持有一个非 const 引用时,你可以合法地使用一个非 const 方法:

std::vector<int>& VectorHolder::getVector() {
  return myVector; // << ok
}

最后,在某些情况下,你可以返回一个值:

std::vector<int> VectorHolder::getVector() const {
  return myVector; // << ok
}

因为复制不需要改变数据,并且不会暴露内部数据。

所以你最终会经常声明这两个变量。

声明这两个变量的结果是:

VectorHolder m;
const VectorHolder c;

m.getVector().size(); // << ok
c.getVector().size(); // << ok - no mutation

m.getVector().push_back(a); // << ok
c.getVector().push_back(a); // << error: attempt to mutate const reference because the const vector is returned

所以一切都很顺利(除了方法的冗余)。


3

函数getVector可以声明为const。它返回一个可以修改的引用,因此虽然实际函数不会修改类中的任何内容,但调用者将能够修改内部数据。

声明方式如下:

std::vector<int>& getVector();

如果您希望函数返回一个不可修改的向量,那么请在向量和函数上都使用const修饰符:
const std::vector<int>& getVector() const;

0

原因是const成员函数应该只返回const引用。这是因为在const函数中,每个数据成员都变成了常量。

因此,你必须以这种方式声明getVector():

std::vector<int> &VectorHolder::getVector() const;

2
尽管如上所述,暴露内部容器可能并不是一个好主意。如果有一天你决定从 vector 迁移到 map,那么你的用户将会受到影响。我建议实现迭代器。 - Lev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接