Tengo la siguiente pregunta. ¿Cuál de estos es mejor que se debe seguir y por qué?Inicializando ... ¿cuál es más eficiente?
string strMyString = "SampleString";
o
string strMyString("SampleString");
Gracias de antemano.
Tengo la siguiente pregunta. ¿Cuál de estos es mejor que se debe seguir y por qué?Inicializando ... ¿cuál es más eficiente?
string strMyString = "SampleString";
o
string strMyString("SampleString");
Gracias de antemano.
Me respondió que here
Una cosa que he puesto en esta respuesta aquí: Tampoco lo es el uso de cualquier operador de asignación.
Breve explicación para la cosa específica de la cadena. std::string
tiene un constructor toma un argumento que acepta char const*
:
// simplified to a normal class declaration. std::string actually
// is a template instantiation.
class string {
public:
string(char const* str) {
// copy over...
}
};
Ahora vemos que tiene un constructor que toma un puntero a carácter (s). Para que pueda aceptar un literal de cadena. Creo que el siguiente caso es obvio entonces:
string s("hello");
llamará al constructor directa e inicializar s
con ello. Esto se llama inicialización directa.
La otra forma de inicializar una variable se llama copia de inicialización. El estándar dice que para el caso de la inicialización de copia donde el inicializador tiene no el tipo del objeto que se está inicializando, el inicializador se convierte al tipo apropiado.
// uses copy initialization
string s = "hello";
primer lugar, vamos afirman los tipos
s
tiene el tipo std :: string"hello"
es una matriz, que en este caso nuevamente se maneja como un puntero. Por lo tanto, lo consideraremos como char const*
.El compilador busca dos formas de realizar la conversión.
std::string
?Se va a crear un temporal std::string
por una de esas formas que luego se utiliza para inicializar el objeto s
utilizando std::string
's constructor de copia. Y ve std::string
tiene un constructor de conversión que acepta el inicializador. Entonces lo usa.Al final, es efectivamente el mismo que
std::string s(std::string("hello"));
Nota que la forma que se utiliza en su ejemplo que desencadenó todo lo que
std::string s = "hello";
define un conversión implícita. Puede marcar el constructor de tomar la char const*
como explícita para sus tipos si usted se pregunta acerca de las reglas de inicialización de sus cosas, y no va a permitir utilizar el constructor correspondiente como constructor conversión más:
class string {
public:
explicit string(char const* str) {
// copy over...
}
};
¡Con eso, ahora está prohibido inicializarlo usando copy initialization
y char const*
(y en varios otros lugares)!
Ahora, eso era si el compilador no admite la elisión de provisionales en varios lugares. Se permite que el compilador para asumir que un constructor de copia copias en este contexto, y puede eliminar la copia extra de la cadena temporal, y en su lugar construir el std :: string temporal directamente en el objeto inicializado. Sin embargo, el constructor de copia debe ser accesible en particular. Por lo tanto, la inicialización copia no es válida si hace esto
class string {
public:
explicit string(char const* str) {
// copy over...
}
private: // ugg can't call it. it's private!
string(string const&);
};
Ahora realidad, sólo el caso de inicialización directa es válido.
Tu respuesta es correcta. El mío estaba mal, así que eliminé el mío. +1 porque aprendí algo nuevo. – MrValdez
Impresionante! Obtener el doble de los "puntos brownie" en esencia la misma respuesta! –
La única diferencia real es que el primero requiere técnicamente uso del constructor de copia, pero se permite el compilador para eludir de manera que la eficiencia será idéntico en ambos casos.
Sin embargo, el primero requiere que el constructor de copia sea accesible (es decir, no privado), incluso si no se utiliza realmente.
Compilar ambos, observe el ensamblador. El primero es uno menos de instrucciones ...
; 9 : std::string f("Hello");
push OFFSET [email protected][email protected][email protected]
lea ecx, DWORD PTR _f$[esp+80]
call DWORD PTR [email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@Z
; 10 : std::string g = "Hello";
push OFFSET [email protected][email protected][email protected]
lea ecx, DWORD PTR _g$[esp+80]
mov DWORD PTR __$EHRec$[esp+88], 0
call DWORD PTR [email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@Z
... pero eso es un artefacto, ya que fue la primera en la sierra compilador. Cambiar el código mediante el canje de la orden:
; 9 : std::string g1 = "Hello";
push OFFSET [email protected][email protected][email protected]
lea ecx, DWORD PTR _g1$[esp+136]
call DWORD PTR [email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@Z
; 10 : std::string f1("Hello");
push OFFSET [email protected][email protected][email protected]
lea ecx, DWORD PTR _f1$[esp+136]
mov DWORD PTR __$EHRec$[esp+144], 0
call DWORD PTR [email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@Z
... y he aquí, el segundo es uno menos de instrucciones.
También vemos que este compilador (Microsoft VC++ 2005, la configuración de la versión) genera el mismo ensamblador para ambas versiones. Por lo tanto, no hay diferencia en este compilador, y usted puede probarlo.
en este caso es la mejor manera ... en los casos en que el compilador no puede ver ciertas cosas, puede ser más eficiente a la inversa, ya que predice el compilador en la dirección correcta. –
Las otras respuestas son los correctos, pero por favor recuerde que también que probablemente no importa. Va a ser raro, muy raro, increíblemente raro, que la eficiencia de inicialización de cadenas afecte la velocidad de su programa incluso en una fracción de segundo.
La pregunta en sí es diversión porque ayuda a mostrar las operaciones de los constructores y asignaciones de C++, pero en la práctica si estás perdiendo el tiempo tratando de optimizar esto (y publicar en SO es evidencia suficiente de que eres ..) realmente estás inclinándote en los molinos de viento.
Es mejor evitar la distracción y gastar su esfuerzo en otro lado.
¿en qué idioma se supone que debe estar? –
asumiendo que esto es std :: string? – RedBlueThing
hago C++ pero supongo que puede aplicarse a cualquier lenguaje basado en c (C# y java) – vj01