Pregunta

He ir a una pregunta muy simple, pero por desgracia no puedo averiguar la respuesta a mí mismo.

Supongamos que tengo un poco de estructura de datos que contiene los ajustes y actúa como un mapa de configuración. Tengo un método GetValue(const std::string& name), que devuelve el valor correspondiente.

Ahora estoy tratando de averiguar - ¿qué tipo de enfoque de rentabilidad-valor sería mejor. Los medios obvia haciendo mi método actúan como

std::string GetValue(const std::string& name) const

y devuelve una copia del objeto y se basan en RVO en los significados de rendimiento.

El otro significaría haciendo dos métodos

std::string& GetValue(...)
const std::string& GetValue(...) const

que generalmente significa la duplicación de código o el uso de algunos moldes mal constantes para usar una de estas rutinas dos veces.

#Q

¿Cuál sería su elección en este tipo de situación y por qué?

¿Fue útil?

Solución

En realidad yo probablemente utilizar:

std::string GetValue(const std::string& name) const;
// or
const std::string* GetValue(const std::string& name) const;

void SetValue(std::string name, std::string value);

Setter primero:

  • Pasando por valor de SetValue permite al compilador algunas optimizaciones que no se pueden hacer con pase por const referencia, se ha explicado en un artículo por Dave Abrahams, "¿Quieres velocidad? paso por valor."
  • El uso de un Setter suele ser mejor, ya que se puede comprobar el valor de ser conjunto mientras que con una clara referencia que no tiene ninguna garantía de que la persona que llama no va a hacer nada estúpido con los datos.

Para el comprador:

  • Al regresar por la copia parece un desperdicio ya que la mayoría de veces no modificará el objeto devuelto (para una configuración del mapa), sin embargo puntero o una referencia significan que el objeto alias vivirá lo suficiente, si no se puede garantizar que se el punto es discutible: el retorno por valor. También copiar permitirá evitar la exposición de un detalle interno, por ejemplo si de repente a cambiar a std::wstring porque necesita algunos ajustes en UTF-8 ...
  • Si necesita el rendimiento, entonces usted está listo para hacer algunas concesiones en este departamento. Sin embargo una referencia no permite señalar la ausencia de la propiedad (a menos que tenga algún valor mágico), mientras que el puntero hace que sea fácil (NULL ya está cortado para usted).

Otros consejos

Eso depende del uso. Debe GetValue("foo") = "bar" sentido? En ese caso, el retorno por valor no hace lo que quiere.

Si usted puede regresar por referencia constante, lo hace. La única razón para volver a una clase de memoria de la gestión como std :: string por valor es porque es una cadena temporal.

Este es un punto muy "sensible" de C ++. En mi humilde opinión es uno de los puntos más débiles del diseño de C ++. Que yo sepa no hay muy buena elección, que será a la vez aspecto y rendimiento bueno.

Un punto que debe mencionarse que RVO optimización general lo hace sólo una parte del trabajo. Sin ella una expresión típica de esta manera:

std::string txt = GetValue("...");

en realidad producir 2 copias! Depende del compilador, pero por lo general RVO elimina la optimización de una sola copia, sin embargo el otro está todavía allí.

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