Internamente y sobre el código generado, ¿existe realmente una diferencia entre:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
y
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
Gracias...
Internamente y sobre el código generado, ¿existe realmente una diferencia entre:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
y
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
Gracias...
Suponiendo que esos valores son tipos primitivos, entonces no, no hay diferencia. Las listas de inicialización solo hacen una diferencia cuando tiene objetos como miembros, ya que en lugar de usar la inicialización predeterminada seguida de la asignación, la lista de inicialización le permite inicializar el objeto a su valor final. De hecho, esto puede ser notablemente más rápido.
Necesita usar la lista de inicialización para inicializar miembros constantes, referencias y clase base
Cuando necesite inicializar miembros constantes, referencias y pasar parámetros a constructores de clases base, como se menciona en los comentarios, debe usar la lista de inicialización.
La clase / estructura de ejemplo (no exhaustiva) contiene una referencia:
Y ejemplo de inicialización de la clase base que requiere un parámetro (por ejemplo, sin constructor predeterminado):
fuente
_capacity
,_data
y_len
tienen tipos de clase sin constructores predeterminados accesibles?const
miembro en el cuerpo del constructor, debe usar la lista de inicialización; los noconst
miembros pueden inicializarse en la lista de inicialización o en el cuerpo del constructor.Si. En el primer caso puedes declarar
_capacity
,_data
y_len
como constantes:Esto sería importante si desea garantizar la
const
idoneidad de estas variables de instancia al calcular sus valores en tiempo de ejecución, por ejemplo:const
las instancias deben inicializarse en la lista de inicializadores o los tipos subyacentes deben proporcionar constructores públicos sin parámetros (lo que hacen los tipos primitivos).fuente
Creo que este enlace http://www.cplusplus.com/forum/articles/17820/ ofrece una excelente explicación, especialmente para aquellos que son nuevos en C ++.
La razón por la que las listas de inicializadores son más eficientes es que dentro del cuerpo del constructor, solo tienen lugar las asignaciones, no la inicialización. Entonces, si está tratando con un tipo no incorporado, el constructor predeterminado para ese objeto ya ha sido llamado antes de ingresar el cuerpo del constructor. Dentro del cuerpo del constructor, estás asignando un valor a ese objeto.
En efecto, esta es una llamada al constructor predeterminado seguida de una llamada al operador de asignación de copia. La lista de inicializadores le permite llamar directamente al constructor de copia, y esto a veces puede ser significativamente más rápido (recuerde que la lista de inicializadores está antes del cuerpo del constructor)
fuente
Agregaré que si tiene miembros de tipo de clase sin un constructor predeterminado disponible, la inicialización es la única forma de construir su clase.
fuente
Una gran diferencia es que la asignación puede inicializar miembros de una clase principal; el inicializador solo funciona en miembros declarados en el ámbito de clase actual.
fuente
Depende de los tipos involucrados. La diferencia es similar entre
y
donde la segunda forma es la lista de inicialización, es decir, hace una diferencia si el tipo requiere argumentos de constructor o es más eficiente con argumentos de constructor.
fuente
La verdadera diferencia se reduce a cómo el compilador gcc genera código de máquina y coloca la memoria. Explique:
Ciertamente, hay otras formas de manejar miembros de tipo constante. Pero para facilitarles la vida, los escritores del compilador de gcc deciden establecer algunas reglas
fuente
Solo hay una forma de inicializar instancias de clase base y variables miembro no estáticas y es usar la lista de inicializadores.
Si no especifica una variable de miembro base o no estática en la lista de inicializadores de su constructor, entonces ese miembro o base se inicializará por defecto (si el miembro / base es un tipo de clase que no es POD o una matriz de clase que no es POD tipos) o dejar sin inicializar de otra manera.
Una vez que se ingresa el cuerpo del constructor, todas las bases o miembros se habrán inicializado o dejado sin inicializar (es decir, tendrán un valor indeterminado). No hay ninguna oportunidad en el cuerpo del constructor para influir en cómo se deben inicializar.
Es posible que pueda asignar nuevos valores a miembros en el cuerpo del constructor, pero no es posible asignar a
const
miembros o miembros de tipo de clase que se han hecho no asignables y no es posible volver a vincular referencias.Para tipos incorporados y algunos tipos definidos por el usuario, la asignación en el cuerpo del constructor puede tener exactamente el mismo efecto que inicializar con el mismo valor en la lista de inicializadores.
Si no nombra un miembro o una base en una lista de inicializadores y esa entidad es una referencia, tiene un tipo de clase sin un constructor predeterminado declarado por el usuario accesible, está
const
calificado y tiene un tipo POD o es un tipo de clase POD o matriz de tipo de clase POD que contiene unconst
miembro calificado (directa o indirectamente), el programa está mal formado.fuente
Si escribe una lista de inicializadores, lo hace todo en un solo paso; si no escribe una lista de iniciadores, realizará 2 pasos: uno para la declaración y otro para asignar el valor.
fuente
Existe una diferencia entre la lista de inicialización y la declaración de inicialización en un constructor. Consideremos el siguiente código:
Cuando se usa MyClass, todos los miembros se inicializarán antes de que se ejecute la primera instrucción en un constructor.
Pero, cuando se usa MyClass2, todos los miembros no se inicializan cuando se ejecuta la primera instrucción en un constructor.
En un caso posterior, puede haber un problema de regresión cuando alguien agregó código en un constructor antes de que se inicialice un miembro determinado.
fuente
Aquí hay un punto que no vi a otros referirse a él:
La clase temporal no tiene un ctor predeterminado. Cuando lo usamos en otra clase de la siguiente manera:
el código no se compilará, porque el compilador no sabe cómo inicializar
obj
, porque solo tiene un ctor explícito que recibe un valor int, por lo que tenemos que cambiar el ctor de la siguiente manera:Por lo tanto, no se trata solo de constantes y referencias.
fuente