Quiero decir, es una cuestión de elegir palabras más que cualquier diferencia entre la función y la llamada al constructor. La cosa que se llama "constructor de un objeto" también se puede llamar "función con object
tipo de retorno de nombre object
".
Se podría argumentar que C ++ no permite que uno tenga la misma función y nombre de tipo; Sin embargo, hay una solución para hacerlo. C ++ tiene un azúcar sintáctico especial (que se denomina constructor) con el que puede crear una función con el object
tipo de retorno de nombre object
. Así que creo que un constructor se puede ver y usar como una función independiente.
¿Hay algunas diferencias semánticas importantes que me estoy perdiendo aquí?
c++
functions
constructors
type
usuario3123061
fuente
fuente
Respuestas:
Un constructor es básicamente un método, sí, pero es un método especial.
Por ejemplo, en C ++ un constructor no es simplemente una función que devuelve una nueva instancia de ese tipo. Si lo fuera, la herencia no funcionaría. No se podía llamar a los constructores base, porque también devolverían una nueva instancia. Terminaría con una nueva instancia de A, que luego se devuelve al constructor de B que crea una nueva instancia de B, que luego se devuelve al constructor de C, etc.
En cambio, un constructor es más un método de inicialización que el asignador de instancias llama automáticamente. Cuando, por ejemplo, llama a "nuevo" para hacer un objeto en el montón, asigna la memoria para el tipo que solicitó (usando un asignador de memoria, como malloc), luego llama al método del constructor. El compilador tiene reglas especiales sobre cómo, y en qué orden, ese constructor puede llamar a los otros constructores. Por ejemplo, en C #, si no llama explícitamente a un constructor base, el compilador agregará una llamada al constructor predeterminado base.
Son esas reglas acerca de cómo el compilador maneja los constructores lo que lo hace diferente de "una función llamada .ctor que devuelve una instancia del tipo".
fuente
new
para construir objetos en C ++, ya que tiene variables automáticas.No, un constructor de
object
es muy diferente de una función llamadaobject
y que regresaobject
. Un constructor no tiene nombre, pero eso es en gran medida un tecnicismo. Las diferencias más importantes son que un constructor no tiene tipo de retorno y que no se puede llamar directamente.Un constructor no devuelve nada porque se le asigna un bloque de memoria y opera en esa memoria en el lugar. Podría ayudar si olvida el nombre "constructor" por un momento y piensa en él como un inicializador . El propósito del constructor no es construir un objeto "de la nada". Su propósito es inicializar un objeto en el lugar preciso de la memoria donde debe estar.
Si un constructor devolviera un objeto, ese objeto devuelto (el valor de retorno) tendría que vivir en algún lugar (probablemente en la pila), y allí, tendría que inicializarse de alguna manera , estamos corriendo en un bucle aquí.
Esto va de la mano con el hecho de que un constructor nunca puede ser llamado directamente. Si tiene una clase
object
y usa una expresión enobject()
alguna parte, no tiene la semántica de "llamar al constructor deobject
". Tiene la semántica de "crear un objeto de tipo temporalobject
". El compilador traduce esto en la asignación de un lugar para que el temporal viva (probablemente / comúnmente en la pila), y llama al constructor para construir (= inicializar) un objeto en ese lugar.El mismo principio se aplica cuando se usa
new object()
. Esta es una nueva expresión, que hace dos cosas:operator new
(que devuelve avoid*
) para asignar memoria sin procesar para el objeto.Pensando en un constructor de
object
como una función como esta:Está Mal. En todo caso, la forma en que funciona un constructor está más cerca de esto:
Con la excepción de que nunca puedes llamarlo directamente. Está siempre sólo se llama cuando especificado por una construcción del lenguaje diferente. Incluso la colocación nueva (también conocida como el truco "llamar a un constructor aquí")
new (&place_for_object) object()
no llama al constructor directamente. Se traduce en una llamada a la forma de colocación nueva,operator new
que devuelve su argumento, seguido de una llamada al constructor (como cualquier otra expresión nueva).fuente
Su intento de volver a redactar es incorrecto.
Aunque un constructor parece una función miembro con un nombre igual al nombre de la clase, el hecho es que un constructor realmente no tiene un nombre. Esto se establece explícitamente en el estándar C ++ (sección [class.ctor] / 1):
En cuanto a: "Creo que un constructor se puede ver y usar como una función independiente" va ... bueno, no estoy muy seguro de lo que quieres decir. Una función libre ciertamente no puede ser un constructor, un constructor debe ser miembro de una clase. Al mismo tiempo, ciertamente puede definir una función libre que crea un objeto y devuelve una instancia de ese objeto. Esa función libre puede incluso (más o menos) tener el mismo nombre que el tipo de objeto que crea, si lo desea lo suficiente. Por ejemplo, podría definir la clase dentro de un espacio de nombres, luego definir una función fuera del espacio de nombres:
Este no es realmente el mismo nombre (la función es justa
bar
y la clase esfoo::bar
), pero dependiendo de su punto de vista, podría mirarlos de esa manera de todos modos.Sin embargo, una función libre de este tipo no tendría las otras características clave de un constructor. La invocación de un constructor puede ser completamente implícita. Por ejemplo, si tengo una clase como:
... luego código como:
... puede crear un objeto foo temporal a partir del
1
para que pueda pasar ese objeto foo afoo::operator+
. Eso simplemente no sucederá con una función libre, incluso si esa función libre se definió para tomar el tipo de parámetro correcto y devolver el tipo de resultado requerido. Para una conversión tan implícita, se requiere un constructor.fuente
Primero, los constructores no devuelven nada y, como consecuencia, no tienen tipos de retorno.
En segundo lugar, los constructores son diferentes en el sentido de que no se puede llamar al constructor directamente de la misma manera que se llaman funciones. En cambio, si declara una variable, el tiempo de ejecución llamará a los constructores apropiados.
Tercero, en caso de herencia, las funciones regulares en las subclases anulan las funciones en las clases primarias. Constructores, por otro lado, los constructores de cascada - clase primaria se llaman primero, luego los constructores de subclase.
Cuarto, los constructores pueden tener listas de inicialización, mientras que la función "normal" no.
fuente