punteros parametros herencia funciones ejemplos destructores definicion constructores como codigo clases arreglos c++ vector reference const

parametros - herencia c++



Referencia de devoluciĆ³n a una variable miembro de vector (4)

Tengo un vector como miembro en una clase y quiero devolver una referencia a él a través de una función getVector () para poder modificarlo más tarde. ¿No es mejor que la función getVector () sea const? Sin embargo, recibí un error "calificadores caídos en referencia de vinculación de tipo ..." en el siguiente código. ¿Qué debería 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; }


Como es una función de miembro const , el tipo de retorno no puede ser una referencia no constante. Hazlo const :

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

Ahora está bien.

¿Por qué está bien? Porque en una función const , cada miembro se convierte en constante de tal manera que no se puede modificar, lo que significa que myVector es un vector const en la función, es por eso que también debe crear el tipo de retorno const , si regresa la referencia .

Ahora no puedes modificar el mismo objeto. Vea lo que puede hacer y lo que no puede:

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

Por cierto, me pregunto por qué necesitas ese VectorHolder en primer lugar.


La función getVector se puede declarar como const . Devuelve una referencia que se puede modificar, de modo que mientras la función real no modifique nada en la clase, la persona que llama podrá modificar los datos internos.

Declararlo como:

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

Si desea que una función devuelva un vector que no se puede modificar, use el modificador const tanto en el vector como en la función:

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


La razón es que una función de miembro const solo debería devolver referencias de referencias. Esto se debe a que en una función const, cada miembro de datos se vuelve constante.

Por lo tanto, debe declarar el getVector () de esta manera:

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


no es inusual declarar variantes const y mutable, así:

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

el problema subyacente con su programa es que devuelve una referencia no constante de un método const.

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

entonces hazlo const usando esta forma:

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

y cuando esto es un método no const o el cliente tiene una referencia no const, entonces legalmente puede usar un método no const:

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

finalmente, puede devolver un valor (en algunos casos):

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

porque la copia no requiere mutación y no proporciona exposición a los datos internos.

por lo que terminará declarando ambas variantes con bastante frecuencia.

los resultados de declarar ambos son:

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

para que todo salga bien (aparte de la redundancia de los métodos).