2009-12-26 22 views
5

Estoy aprendiendo C++ por el momento, C++ Primer plus. Pero solo quería visitar el sitio web de cplusplus y omitir un poco el manejo de archivos.'Inicialización del soporte'. (C++)

Conozco bastante las bases del manejo de archivos provenientes de java, php, visual basic. Pero encontré una línea bastante extraña.

ostream os(&fb); 

fb representa un archivo de imagen. Yo no lo entiendo la sintaxis de este, pero puedo imaginar que es lo mismo que:

ostream os = &fb; 

Pero nunca leí sobre esta manera de inicializar las variables.

Así que me pregunto. ¿No tengo sentido y me pierdo una característica realmente útil todo el tiempo? ¿Es esta forma de inicialización simplemente vieja? ¿Es algo diferente?

Gracias de antemano.

Respuesta

5

Tal vez debería leer this y this

+0

Gracias por esta gran referencia y respuesta rápida :) –

+5

Debe proporcionar la respuesta aquí, en esta publicación. El enlace puede estar desactivado cuando alguien más necesita que se responda esta pregunta, y oye, si quieres el representante, debes publicar la respuesta real. Es común SO cortesía. – jalf

+0

Parafraseado ligeramente del segundo enlace: 'ostream os = &fb;' es la inicialización de la copia, y 'os' siempre se inicializa con el copiador de' ostream'. (El "=" es solo un remanente de sintaxis de C; operator = nunca se llama.) El compilador en realidad está permitido (pero no es obligatorio) para optimizar la construcción de copias en este tipo de situaciones. Si lo optimiza, la copiadora debe estar accesible. ** Pauta: ** Prefiere usar el formulario 'ostream os (& fb)'. Siempre funciona dondequiera que funcione 'ostream os = & fb', y tiene otras ventajas (por ejemplo, puede tomar múltiples parámetros). –

5

Un pequeño programa para ver cuando constructor de copia se llama y cuando la función de operador de asignación sobrecargado se llama:

#include <iostream> 

using namespace std; 

class test 
{ 
    public: 
     // default constructor. 
     test() 
     { 
      cout<<"Default Ctor called"<<endl; 
     } 

     // copy constructor. 
     test(const test& other) 
     { 
      cout<<"Copy Ctor called"<<endl; 
     } 

     // overloaded assignment operator function. 
     test& operator=(const test& other) 
     { 
      cout<<"Overload operator function called"<<endl; 
      return *this; 
     } 
}; 

int main(void) 
{ 
    test obj1; // default constructor called. 

    test obj2 = obj1; // copy constructor called. 

    test obj3(obj2); // again copy constructor called. 

    obj1 = obj2; // overloaded assignment operator function. 

    return 0; 
} 

Salida:

Default Ctor called 
Copy Ctor called 
Copy Ctor called 
Overload operator function called 

Entonces, en su caso, se llama al constructor de copias de ostream en ambas ocasiones.

+0

Parece que estaba bastante correcto entonces: D. Gracias por la explicación clara. ¡Felices vacaciones! –

6

Ambas formas realizan la inicialización . La primera sintaxis (con ()) se denomina sintaxis de inicialización directa. La segunda sintaxis (con =) se denomina sintaxis de inicialización de copia. Actuarán igual en la mayoría de los casos de la vida real, pero de hecho hay diferencias entre los dos.

En situaciones en las que los tipos en el lado izquierdo (LHS) y el lado derecho (RHS) son idénticos (ignorando cualquier calificador const/volátil), ambos son exactamente iguales. El estándar de lenguaje establece explícitamente que en este caso el formulario = es equivalente al formulario ().

Pero cuando los tipos son diferentes (y el tipo LHS es un tipo de clase), estas dos formas generalmente funcionarán de manera diferente.

  • La forma de copia de inicialización funciona como sigue: convertir el valor RHS al objeto temporal del tipo LHS (por cualquier medio posible: conversión estándar, operador de conversión, constructor de conversión). Y luego use el constructor de copia de la clase LHS para copiar el objeto temporal al objeto LHS.

  • La forma de inicialización directa funciona de la siguiente manera: simplemente considere todos los constructores de LHS y elija el más apropiado mediante el uso de la resolución de sobrecarga.

Se nota inmediatamente que la sintaxis de copia de inicialización incondicionalmente utiliza el constructor de copia (la copia y el temporal intermedio puede ser optimizado de distancia, pero conceptualmente está allí).Si la clase LHS no tiene un constructor de copia accesible, la inicialización de la copia se vuelve inconstante, mientras que la inicialización directa puede funcionar.

Además, la palabra clave explicit aplicada a determinado constructor afectará a la forma de inicialización disponible para cada combinación de tipos.

+1

Simplemente vamos a elegir esa palabra * exactamente * (ya que la respuesta suena como si fuera una respuesta realmente estándar): si el constructor de copia es explícito, la sintaxis '=' fallará en caso de que LHR y RHS sean las mismas tipo, mientras que el formulario '()' no fallará. –

0

Según tengo entendido, & var es un alias para la variable var y no importa cuál use.

-------- ----------------- adición

El código siguiente es tomado de BS book.From esto es claro que ambos son alias a la misma variable. También dice lo siguiente.

"La semántica del paso de argumento se define como la inicialización, por lo que cuando se llama, el argumento de incremento aa se convierte en otro nombre de x." Es por eso que me referí a & x para ser un alias de x.

void increment(int& aa) { aa++; }

void f() { int x = 1; increment(x); }

+0

No, '& var' es la dirección de' var'. Ellos tienen diferentes tipos; si var es tipo T, entonces & var es tipo T *. –

+0

He editado mi respuesta. Compruébelo por favor. – Boolean

1

Un beneficio importante de la función de inicialización de guardia es que también trabajan con los constructores que toman múltiples argumentos. Por ejemplo, un constructor de fstream puede tomar dos parámetros:

std::fstream file("filename", ios_base::out); 

Hasta C++0x uniform initialization está ampliamente disponible, la inicialización de la función de llamada es la única manera de manejar varios constructores de argumentos.

Cuestiones relacionadas