¿Cómo evitar llamar explícitamente a un constructor al pasar un objeto temporal por referencia en C ++?

StackOverflow https://stackoverflow.com/questions/1008272

  •  06-07-2019
  •  | 
  •  

Pregunta

Digamos que tengo una clase:

class String
{
public:
     String(char *str);
};

Y dos funciones:

void DoSomethingByVal(String Str);
void DoSomethingByRef(String &Str);

Si llamo a DoSomethingByVal de esta manera:

DoSomethingByVal("My string");

el compilador descubre que debe crear un objeto String temporal y llamar al constructor char *.

Sin embargo, si trato de usar DoSomethingByRef de la misma manera, obtengo un " No se puede convertir el parámetro de 'char *' a 'String & amp;' " error.

En cambio, tengo que crear explícitamente una instancia:

DoSomethingByRef(String("My string"));

que puede ser bastante molesto.

¿Hay alguna forma de evitar esto?

¿Fue útil?

Solución

Debe pasar por referencia constante:

Para:

void DoSomethingByVal(String Str);

En esta situación, el compilador primero crea una variable temporal. Luego, la variable temporal se copia incorporada en el parámetro.

Para:

void DoSomethingByRef(String const& Str);

En esta situación, el compilador crea una variable temporal. Pero las variables temporales no se pueden vincular a una referencia, solo se pueden vincular a una referencia constante, por lo que no se puede invocar su función original. Tenga en cuenta que el constructor de objetos std :: string toma una referencia constante que es el parámetro del constructor de copia y es por eso que la primera versión funciona ya que la temporal está vinculada al parámetro de referencia constante del constructor de copia solamente.

Otros consejos

Hmm, no estoy seguro si

void DoSomethingByRef(String &Str);
DoSomethingByRef(String("My string"));

en realidad se compilaría. Un valor r no puede vincularse a una referencia a no constante (porque una referencia a no constante indica que modificará el valor, y no tendría sentido modificar un temporal). ¿Estás seguro de que no estás haciendo:

String str("My string");
DoSomethingByRef(str);

Si desea que DoSomethingByVal tome un valor r, el parámetro debe ser una referencia a const:

void DoSomethingByRef(const String &Str);

Hacer:

DoSomethingByRef (const String & amp; str);

" Mi cadena " no es una cadena, es una cadena c, un char *, si lo desea. Debe colocar esa cadena c en un objeto String, y ENTONCES puede pasar el nuevo objeto String por referencia.

Otro punto, ya estás pasando un char * ... eso es bastante ligero, solo un puntero. ¿Por qué preocuparse por pasar un nuevo objeto por referencia? Simplemente asigne un nuevo objeto dentro de ese constructor desde el montón y copie la cadena c en él.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top