herencia - Constructor predeterminado vs. implícito en C++
string c++ (2)
Esto es muy trivial, pero el idioma checo (mi nativo) no distingue entre implícito y predeterminado, así que estoy confundido por algunas traducciones checas, ¿cuál es la diferencia entre el constructor implícito y el predeterminado o la llamada del constructor?
struct Test {
Test(int n=0) { }
};
¿Puedes describir en estos términos lo que es:
- Prueba t1;
- Prueba t2 ();
- Prueba t3 = 3;
- Prueba t4 (4);
- Prueba t5 = Prueba (5);
?
Los términos predeterminados e implícitos , cuando se habla de un constructor tienen el siguiente significado:
el constructor predeterminado es un constructor al que se puede llamar sin argumentos. No toma argumentos o tiene valores predeterminados para cada uno de los argumentos tomados.
constructor implícito es un término comúnmente utilizado para hablar de dos conceptos diferentes en el lenguaje, el
constructor implícitamente declarado que es un constructor predeterminado o de copia que se declarará para todas las clases de usuarios si no se proporciona un constructor definido por el usuario (predeterminado) o no se proporciona ningún constructor de copia (copia). Es decir, una clase sin constructores declarada por el usuario tiene un constructor predeterminado implícitamente declarado.
El constructor implícitamente definido es un constructor declarado implícitamente que se usa ( odr-used 1 en el lenguaje y para el cual el compilador proporcionará una definición.
struct test { test(int i = 0) { } // test(test const&) implicitly declared here }; struct test2 { }; // implicitly declared: test2(), test2(test2 const&) int main() { test t; test copy(t); // causes *definition* of the implicitly // declared copy constructor test2 t2; // causes *definition* of test2::test2() test2 copy2(t2); // causes *definition* of test2::test2(test2 const&) }
En términos simples, un constructor es predeterminado si se puede invocar sin argumentos. Un constructor está implícito (declarado / definido) si el usuario no lo proporciona pero lo declara / define.
A partir de los casos específicos:
Test t1;
Utiliza el constructor predeterminado, Test(int = 0)
, que no está implícito.
Test t2();
Esta es una extraña peculiaridad del lenguaje, declara una función que no toma argumentos y devuelve un objeto Test
.
Test t3 = 3;
Esto se denomina inicialización de copia y es equivalente a la composición de una conversión implícita * de 3
a Test
y copia la construcción de t3
partir del resultado de la conversión. Esto usará el constructor Test(int)
para la conversión y luego el constructor de copia implícitamente definido (y declarado ). Nota: el compilador puede optimizar la copia, pero debe verificar que el constructor de copia esté disponible (especificadores de acceso) y se pueda definir.
Test t4(4);
Utiliza el constructor Test(int)
, que en este caso no actúa como un constructor predeterminado .
Test t5 = Test(5);
Equivalente a la Test t3 = 3
casos, con la única diferencia de que la conversión de 5
a Test
es explícita en este caso. En este ejemplo, no importará, pero si el constructor hubiera sido marcado como explicit
esta línea se compilaría mientras que el caso de t3
fallaría.
*) Otro uso más de lo implícito , en este caso se refiere al hecho de que la conversión de 3
a Test
no se solicita explícitamente en el código. Compare esto con t5
donde la conversión es solicitada explícitamente por el programador: Test(5)
.
Parece que estás confundiendo algunos de los términos. Un constructor predeterminado es uno que no toma parámetros, una llamada implícita es cuando llama directamente al constructor.
De todas formas:
1) Prueba t1;
Constructor predeterminado.
2) Prueba t2 ();
Declaración de función.
3) Prueba t3 = 3;
Copiar inicialización. Llamará al constructor de conversión, creará una Test
temporal desde 3
y usará el constructor de copia para crear t3
.
4) Prueba t4 (4);
Inicialización directa. Utiliza el constructor de conversión directamente.
5) Prueba t5 = Prueba (5);
Copiar inicialización. Similar a 3).