todas tipos retorno parametros las funciones funcion ejemplos ejemplo con c++ compiler-construction const

tipos - todas las funciones de c++



En c++, ¿por qué el compilador elige la función no const cuando la const también funcionaría? (4)

Por ejemplo, supongamos que tengo una clase:

class Foo { public: std::string& Name() { m_maybe_modified = true; return m_name; } const std::string& Name() const { return m_name; } protected: std::string m_name; bool m_maybe_modified; };

Y en otro lugar del código, tengo algo como esto:

Foo *a; // Do stuff... std::string name = a->Name(); // <-- chooses the non-const version

¿Alguien sabe por qué el compilador elegiría la versión no const en este caso?

Este es un ejemplo un tanto artificial, pero el problema real que estamos tratando de resolver es guardar automáticamente un objeto periódicamente si ha cambiado, y el puntero debe ser no const porque podría ser cambiado en algún momento.


Dos respuestas vienen a la mente:

  1. La versión no const es una coincidencia más cercana.

  2. Si llamaba a la const sobrecarga para el caso no const, ¿bajo qué circunstancias llamaría alguna vez a la sobrecarga sin const?

Puedes hacer que use la otra sobrecarga lanzando a a const Foo * .

Editar: a partir de anotaciones en C ++

Anteriormente, en la sección 2.5.11, se introdujo el concepto de sobrecarga de funciones. Allí notó que las funciones miembro pueden estar sobrecargadas simplemente por su atributo const. En esos casos, el compilador utilizará la función miembro que coincida más estrechamente con la calificación const del objeto:


El compilador no tiene en cuenta cómo está utilizando el valor de retorno en su determinación; eso no es parte de las reglas. No sabe si lo estás haciendo

std::string name = b->Name();

o

b->Name() = "me";

Tiene que elegir la versión que funcione en ambos casos.


Porque a no es un puntero de const. Por lo tanto, una función no const es una coincidencia más cercana. Aquí es cómo puede llamar a la función const:

const Foo* b = a; std::string name = b->Name();

Si tiene tanto una const como una sobrecarga no const, y quiere llamar a la const en un objeto no const, esto podría ser una indicación de mal diseño.


Puede agregar una función "cName" que es equivalente a "Name () const". De esta forma, puede llamar primero a la versión const de la función sin convertirla en un objeto const.

Esto es principalmente útil con la nueva palabra clave auto en C ++ 0x, por lo que están actualizando la biblioteca para incluir cbegin (), cend (), crbegin (), crend ​​() para devolver const_iterator incluso si el objeto no es const.

Lo que está haciendo es probablemente mejor si tiene una función setName () que le permite cambiar el nombre en lugar de devolver una referencia al contenedor subyacente y luego "tal vez" se modifica.