A menudo he visto que las personas crean objetos en C ++ usando
Thing myThing("asdf");
En lugar de esto:
Thing myThing = Thing("asdf");
Esto parece funcionar (usando gcc), al menos mientras no haya plantillas involucradas. Mi pregunta ahora, ¿es correcta la primera línea y si es así debo usarla?
Respuestas:
Ambas líneas son correctas, pero hacen cosas sutilmente diferentes.
La primera línea crea un nuevo objeto en la pila llamando a un constructor del formato
Thing(const char*)
.El segundo es un poco más complejo. Esencialmente hace lo siguiente
Thing
usando el constructorThing(const char*)
Thing
usando el constructorThing(const Thing&)
~Thing()
al objeto creado en el paso 1fuente
Thing myThing = Thing(...)
no utiliza el operador de asignación, sigue siendo una copia construida como se diceThing myThing(Thing(...))
, y no implica una construcción predeterminadaThing
(editar: la publicación se corrigió posteriormente)Supongo que con la segunda línea realmente quieres decir:
cuál sería la forma estándar de crear nuevos objetos dinámicos (necesarios para el enlace dinámico y el polimorfismo) y almacenar su dirección en un puntero. Su código hace lo que JaredPar describió, es decir, crear dos objetos (uno pasó a
const char*
, el otro pasó aconst Thing&
), y luego llamar al destructor (~Thing()
) en el primer objeto (elconst char*
uno).Por el contrario, esto:
crea un objeto estático que se destruye automáticamente al salir del alcance actual.
fuente
El compilador puede optimizar la segunda forma en la primera forma, pero no tiene que hacerlo.
Salida de gcc 4.4:
fuente
En pocas palabras, ambas líneas crean el objeto en la pila, en lugar de en el montón como lo hace 'nuevo'. La segunda línea en realidad implica una segunda llamada a un constructor de copias, por lo que debe evitarse (también debe corregirse como se indica en los comentarios). Debe usar la pila para objetos pequeños tanto como sea posible, ya que es más rápido, sin embargo, si sus objetos van a sobrevivir por más tiempo que el marco de la pila, entonces es claramente la elección incorrecta.
fuente
Idealmente, un compilador optimizaría el segundo, pero no es obligatorio. La primera es la mejor manera. Sin embargo, es bastante crítico comprender la distinción entre pila y montón en C ++, ya que debe administrar su propia memoria de montón.
fuente
Jugué un poco con él y la sintaxis parece ser bastante extraña cuando un constructor no toma argumentos. Déjame dar un ejemplo:
¡así que escribir Thing myThing sin corchetes en realidad llama al constructor, mientras que Thing myThing () hace que el compilador desee crear un puntero de función o algo así!
fuente
En anexar a JaredPar respuesta
1-habitual ctor, 2-función-como-ctor con objeto temporal.
Compile esta fuente en algún lugar aquí http://melpon.org/wandbox/ con diferentes compiladores
Y verás el resultado.
De ISO / IEC 14882 2003-10-15
Su primera y segunda construcción se llaman inicialización directa
Dónde leer sobre RVO:
Desactívelo con el indicador del compilador del comentario para ver dicho comportamiento de copia)
fuente