Denis Sologub
Creo que tiene mucha información al respecto, pero no sé cómo se llama esto. No puedo entender la diferencia entre las siguientes dos cadenas de código:
Object obj();
Y
Object obj = Object();
¿Puede usted explicar por favor? O al menos decir cómo llamarlo.
vladon
Object obj();
no es una instanciación del objeto, es un declaración de una función obj
que no toma argumentos y devuelve una instancia de Object
.
Object obj;
es un default initialization
es decir, creación de instancias con constructor implícito (por lo tanto, constructor implícito predeterminado o no definido por el usuario).explicit
constructor sin parámetros), y esta declaración llama a constructores implícitos de no POD Object
miembros, y para los tipos POD no los inicializa (no se pondrán a cero). Esto es correcto para miembros de miembros de Object
y así sucesivamente recursivamente.
Object obj{};
es un inicialización de lista o inicialización agregada (si Object
es un agregado). Aquellos a los que llamó de manera diferente, para llaves vacías, el comportamiento es el mismo: todos los miembros de los tipos POD se inicializan en cero y los que no son POD se inicializan por defecto.
Object obj = Object();
teóricamente es una declaración de dos pasos: 1) crear temporal Object
instancia; 2) luego construya obj mediante el constructor de copia/constructor de movimiento/operador de copia/operador de movimiento. Pero en la práctica, se construirá de forma predeterminada teniendo en cuenta la elisión de copiar/mover (está habilitado en todos los compiladores modernos de forma predeterminada, incluso con todas las optimizaciones desactivadas, debe deshabilitar la elisión explícitamente). Mejor no uses esta variante.
Preconclusión
Elegir
Object obj;
o
Object obj{};
Elija primero si desea una inicialización rápida sin poner a cero sus miembros POD. Elija el segundo si quiere estar seguro de que todos sus miembros POD serán cero después de la instanciación de Object
.
Prácticamente, antes de la primera lectura de sus miembros, ambas variantes tienen la misma velocidad en tiempo de ejecución en todos los sistemas operativos modernos.
Asi que…
Conclusión
Utilice la inicialización de valor:
Object obj{};
a menos que necesite un rendimiento en tiempo real en sistemas exóticos.
-
debe tener en cuenta que
Object obj{};
es una característica de C++11 y no estaba disponible en versiones anteriores. He tenido que lidiar con esto regularmente, ya que parte de nuestro código fuente es compartido por otro equipo que, por razones técnicas, todavía usa C++ 09, por lo que los archivos comunes a ambos proyectos no pueden usar esta notación.– Darrel Hoffmann
22 de diciembre de 2015 a las 15:54
-
@DarrelHoffman ¡Vamos, hoy termina el 2015! C++14 ES un estándar, C++17 viene.
– vladon
22 de diciembre de 2015 a las 15:56
-
No cambia el hecho de que muchas empresas siguen utilizando los estándares más antiguos. El OP usó la etiqueta C++ y no las etiquetas C++11 (o posterior), por lo que no puede asumir que están usando el último estándar.
– Darrel Hoffmann
22 de diciembre de 2015 a las 15:58
-
@DarrelHoffman ¿Por qué no recuerda Borland Turbo C++ para DOS entonces? Muchas empresas están inundadas de ancianos llamados programadores que simplemente no quieren aprender nada nuevo. He conocido a muchos de esos. Eso es muy malo. También he conocido a varias empresas modernas que usan C++ al borde de los nuevos estándares en producción (incluso para sistemas integrados). Y son los mejores.
– vladon
22 de diciembre de 2015 a las 16:07
-
@vladon: Hay muchos gastos generales en términos de costos de cambio, y muchas empresas todavía se ven obligadas por una variedad de razones a trabajar con código heredado. Claro, si fuera por mí, usaría lo último y lo mejor de todo, pero no siempre tenemos la opción de hacerlo, especialmente en las empresas más grandes que existen desde hace más de una década. Me he metido en problemas más de una vez por usar código de estilo C++ 11 que funciona en mi proyecto pero no compila para otros equipos que usan los mismos archivos con compiladores más antiguos. Solo quería señalar que no todos tienen esa opción.
– Darrel Hoffmann
22 de diciembre de 2015 a las 16:19
Object obj();
declara una función, no un objeto! Esta es una instancia del “Análisis más desconcertante”.
Object obj = Object();
requiere Object
tener un constructor de movimiento o un constructor de copia accesible (aunque el compilador podría terminar eliminando el movimiento/copia).
Las formas simples de crear un objeto incluyen:
Object obj;
Object obj{};
-
¡Gracias! Lo entendí, no lo sé.
– Denis Sologub
21 de diciembre de 2015 a las 20:11
-
Object obj;
yObject obj{};
son diferentes.– vladon
21 dic 2015 a las 20:40
NathanOliver
Object obj();
Declara los nombres de una función obj
que devuelve un Object
y no toma parámetros. Esto generalmente no es lo que quieres.
Object obj = Object();
declara un Object
nombrada obj
luego se inicializa la copia con un valor predeterminado temporal construido Object
. Normalmente, tampoco desea hacer esto a menos que esté restableciendo un objeto a un estado predeterminado.
En general, si desea construir sin llamar a un constructor, puede usar
Object obj;
//or
Object obj{};
-
¡Gracias por la respuesta avanzada!
– Denis Sologub
21 de diciembre de 2015 a las 20:13
-
Object obj{};
es la iniciación del valor, no la inicialización predeterminada. Eso puede marcar la diferencia en algunos casos.– juanchopanza
21 de diciembre de 2015 a las 20:32
Gran diferencia.
El primero es un prototipo de función para una función que no toma argumentos y devuelve un Objeto.
El segundo instancia un objeto llamando al constructor predeterminado. Para evitar dudas, no se llama al operador de asignación.
Elimina los paréntesis en el primer caso para que las declaraciones sean equivalentes.
Bien, ¿por qué entonces tengo un problema cuando uso
Object obj()
pero no entiendo cuando se usaObject obj = Object()
?– Denis Sologub
21 de diciembre de 2015 a las 20:09
@ghostman bueno, deberías estar usando
Object obj;
sin los paréntesis– dabadaba
21 de diciembre de 2015 a las 20:10
@juanchopanza ahora que me fijé en los paréntesis tienes razón, son diferentes. Supuse que OP dijo
Object obj
noObject obj()
.– dabadaba
21 de diciembre de 2015 a las 20:13