ti-enxame.com

Referência de retorno para uma variável de membro de vetor

Eu tenho um vetor como membro em uma classe e quero retornar uma referência a ele por meio de uma função getVector (), para poder modificá-lo posteriormente. Não é melhor praticar a função getVector () para ser const? No entanto, recebi um erro “qualifiers dropped in binding reference of type…” no seguinte código. O que deve ser modificado? 

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;
}
26
arjacsoh

Como é uma função de membro const, o tipo de retorno não pode ser referência não-const. Torne const:

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

Agora está tudo bem. 

Por que tudo bem? Porque em uma função de membro const, o membro every se torna const de tal forma que não pode ser modificado, o que significa que myVector é um vetor const na função, é por isso que você deve fazer o tipo de retorno const também , se retornar a referência.

Agora você não pode modificar o mesmo objeto. Veja o que você pode fazer e o que não pode:

 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

By the way, eu estou querendo saber por que você precisa de tal VectorHolder em primeiro lugar.

30
Nawaz

não é incomum declarar variantes const e mutáveis, assim:

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

o problema subjacente com seu programa é que você retorna uma referência não-const de um método const.

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

então você faz const usando este formulário:

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

e quando isso está em um método non const ou o cliente mantém uma referência não-const, então você pode legalmente usar um método não-const:

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

finalmente, você poderia retornar um valor (em alguns casos):

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

porque a cópia não requer nenhuma mutação e não fornece exposição aos dados internos.

então você acabará declarando ambas as variantes com bastante frequência.

os resultados de declarar ambos são:

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

então tudo funciona muito bem (além da redundância dos métodos).

13
justin

A função getVector pode ser declarada como const. Ele retorna uma referência que pode ser modificada, portanto, enquanto a função real não modifica nada na classe, o chamador poderá modificar os dados internos.

Declará-lo como:

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

Se você quiser que uma função retorne um vetor que não pode ser modificado, use o modificador const no vetor e na função:

const std::vector<int>& getVector() const;
2
Some programmer dude

A razão é que uma função de membro const só deve retornar referências const. Isso ocorre porque, em uma função const, todo membro de dados se torna constante.

Portanto, você tem que declarar o getVector () desta maneira:

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