43 votes

Renvoie la référence à une variable membre du vecteur

J'ai un vecteur comme membre d'une classe et je veux retourner une référence à celui-ci par le biais d'une fonction getVector(), afin de pouvoir le modifier ultérieurement. N'est-il pas préférable que la fonction getVector() soit const ? Cependant j'ai obtenu une erreur "qualifiers dropped in binding reference of type " dans le code suivant. Que faut-il modifier ?

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

47voto

Nawaz Points 148870

Puisqu'il s'agit d'un const la fonction membre, le type de retour ne peut pas être une référence non-const. Il faut const :

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

Maintenant, c'est bon.

Pourquoi est-ce bien ? Parce que dans un const la fonction de membre, chaque membre devient const de manière à ce qu'il ne puisse pas être modifié, ce qui signifie que myVector est un const dans la fonction, c'est pourquoi vous devez rendre le type de retour const également, s'il renvoie le référence .

Maintenant, vous ne peut pas modifier le même objet. Voyez ce que vous pouvez faire et ce que vous ne pouvez pas faire :

 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

D'ailleurs, je me demande pourquoi vous avez besoin d'une telle VectorHolder en premier lieu.

20voto

justin Points 72871

Il n'est pas rare de déclarer des variantes constantes et mutables, comme ceci :

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

le problème sous-jacent de votre programme est que vous retournez une référence non-const depuis une méthode const.

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

donc vous le rendez constant en utilisant ce formulaire :

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

et lorsque cela se trouve dans une méthode non constante ou que le client détient une référence non constante, alors vous pouvez légalement utiliser une méthode non constante :

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

enfin, vous pouvez renvoyer une valeur (dans certains cas) :

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

parce que la copie ne nécessite aucune mutation et ne fournit aucune exposition aux données internes.

vous finirez donc par déclarer les deux variantes assez souvent.

les résultats de la déclaration des deux sont :

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

donc tout fonctionne bien (à part la redondance des méthodes).

2voto

Joachim Pileborg Points 121221

La fonction getVector peut être déclaré comme const . Elle renvoie une référence qui peut être modifiée. Ainsi, bien que la fonction actuelle ne modifie rien dans la classe, l'appelant pourra modifier les données internes.

Déclarez-le comme :

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

Si vous voulez qu'une fonction renvoie un vecteur qui ne peut pas être modifié, utilisez la fonction const sur le vecteur et la fonction :

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

0voto

Lev Points 303

La raison en est qu'une fonction membre const ne doit renvoyer que des références constantes. En effet, dans une fonction const, chaque membre des données devient constant.

Par conséquent, vous devez déclarer le getVector() de cette façon :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X