Comenzando con la programación c ++ para dummies

C ++ está llena de pequeños símbolos, cada uno de los cuales se suma al significado de las expresiones. Las reglas de la gramática C ++ son tan flexibles que estos símbolos se pueden combinar en combinaciones casi impenetrable complejos. Las expresiones en el lenguaje C más simple puede ser tan obtuso que solía haber un concurso anual para que pudiera escribir el programa más oscura y que podría entenderlo.

Nunca es una buena idea para tratar de escribir código complejo pero a veces se ejecutará a través de expresiones en C ++ que son un poco desconcertante a primera vista. Sólo tiene que utilizar los siguientes pasos para descifrarlos:

  1. Comience en el paréntesis más integrados.

    Comience a buscar el mayor número de paréntesis exteriores. Dentro de ellos, buscar paréntesis incrustados. Repita el proceso hasta que haya trabajado su camino a la pareja más profundo de paréntesis. Comience evaluando que subexpresión primero usando las siguientes reglas. Una vez que entienda que la expresión, el pop de vuelta a un nivel superior y repita el proceso.

  2. En el par de paréntesis, evaluar cada operación en orden de precedencia.

    El orden en que se evalúan los operadores está determinada por la precedencia del operador se muestra en la tabla. Indirección viene antes de la multiplicación que viene antes de la adición de este modo la siguiente suma 1 más 2 veces el valor apuntado por ptr *.

int i = 1 + 2 * * ptr-
Los operadores en orden de precedencia
PrecedenciaOperadorSignificado
1() (Unario)Invoca una función
2* Y -> (unario)Referencia a un puntero
2- (unario)Devuelve el negativo de su argumento
3++ (unario)Incremento
3-- (unario)Disminuir
4* (Binario)Multiplicación
4/ (Binario)División
4% (Binario)Modulo
5+ (binario)Adición
5- (binario)Resta
6 (binario)Y lógico
6!!OR lógico
7=, * =,% =, + =, - = (Especial)Tipos de asignación
  1. Evaluar las operaciones de la misma precedencia de izquierda a derecha (excepto la asignación, que va a la inversa).

    La mayoría de los operadores de la misma precedencia evalúan de izquierda a derecha. Así, la siguiente añade 1 a 2 y suma el resultado a 3:

    int i = 1 + 2 + 3

    El orden de evaluación de algunos operadores no importa. Por ejemplo, la adición funciona de la misma de izquierda a derecha como lo hace de derecha a izquierda. El orden de evaluación hace una gran diferencia para algunas operaciones como división. Los siguientes divisiones 8 por 4 y divide el resultado por 2:

    int i = 8/4 / 2-

    La principal excepción a esta regla es la asignación, que se evalúa de derecha a izquierda:

    a = b = c-

    Esto asigna C a B y el resultado a una.

  2. Evaluar subexpresiones en ningún orden en particular.

    Considere la siguiente expresión:

    int i = f () + g () * h () -

    Multiplicación tiene mayor precedencia, por lo que podría suponer que la función g () y h () se llaman antes de f (), sin embargo, este no es el caso. Llamada de función tiene la más alta prioridad de todos, por lo que las tres funciones se llaman antes de realizar cualquiera de la multiplicación o la adición. (Los resultados volvieron de g () y h () se multiplican y luego añaden a los resultados de regresar de f ()).

    La única vez que el orden en que las funciones se llaman marca la diferencia es cuando la función tiene efectos secundarios tales como la apertura de un archivo o cambiar el valor de una variable global. Definitivamente, usted no debe escribir sus programas a fin de que dependen de este tipo de efectos secundarios.

  3. Sólo Realizar cualquier conversión de tipo cuando sea necesario.

    Usted no debe hacer más conversiones de tipos de lo absolutamente necesario. Por ejemplo, la siguiente expresión tiene al menos tres y posiblemente cuatro conversiones de tipos:

    flotar f = 'a' + 1-

    El carbón 'a' debe ser promovido a un int para realizar la adición. El int se convierte entonces en un doble y luego hacia abajo convertido a un solo flotador precisión. Recuerde que toda la aritmética se realiza ya sea en int o double. En general, usted debe evitar realizar aritmética de los tipos de caracteres y evitar solo flotador de precisión por completo.

5 maneras de evitar puntero Problemas en C ++

En C ++, un puntero es una variable que contiene la dirección de un objeto en la memoria interna del equipo. Utilice estos pasos para evitar problemas con los punteros en C ++:

  1. Inicializar punteros cuando se declaran.

    Nunca deje las variables de puntero no inicializado - las cosas no sería tan malo si los punteros no inicializados siempre contienen valores aleatorios - la gran mayoría de valores aleatorios son valores de puntero ilegales y hará que el programa se bloquee tan pronto como se utilizan. El problema es que las variables sin inicializar tienden a asumir el valor de otras variables de puntero, utilizados anteriormente. Estos problemas son muy difíciles de depurar.

    Si usted no sabe qué más para inicializar un puntero, inicializar a nullptr. nullptr se garantiza que sea una dirección ilegal.

  2. Cero fuera punteros después de usarlos.

    Del mismo modo, siempre cero una variable puntero una vez que el puntero no válido asignándole el valor es nullptr. Este es particularmente el caso cuando regresa de un bloque de memoria para el montón usando delete- siempre cero el puntero después de regresar de memoria heap.

  3. Asignar memoria del montón y devolverlo a la pila al mismo "nivel" para evitar pérdidas de memoria.

    Siempre trate de devolver un bloque de memoria para el montón en el mismo nivel de abstracción a medida que se asignan. Esto generalmente significa intentar eliminar la memoria en el mismo nivel de llamadas a funciones.

  4. Coger una excepción para borrar la memoria cuando sea necesario.

    No olvide que puede producir una excepción en casi cualquier momento. Si tiene la intención de atrapar la excepción y mantener operativo (en oposición a dejar que la caída del programa), asegúrese de que usted coge la excepción y devolver los bloques de memoria a la pila antes de que los punteros que apuntan a ellos salen de alcance y la memoria es perdido.

  5. Asegúrese de que los tipos coinciden exactamente.

    Asegúrese siempre de que los tipos de punteros coinciden con el tipo requerido. No refundición un puntero sin alguna razón específica. Considera lo siguiente:

fn void (int * p) -anular myFunc () {char c = 'a'-char * pc = c-fn ((int *) PC) -}

La función anterior compila sin quejarse ya que el pC puntero del personaje se ha reformulado a un int * para que coincida con la declaración de fn (int *) - Sin embargo, este programa es casi seguro que no funciona. La función fn () espera un puntero a un entero de 32 bits y no una mala muerte de 8 bits carbón. Este tipo de problemas son muy difíciles de resolver.

¿Cómo y cuándo hacer copias profundas en C ++

Las clases que asignan los recursos en su constructor normalmente deben incluir un constructor de copia para crear copias de estos recursos. La asignación de un nuevo bloque de memoria y copiar el contenido del original en este nuevo bloque se conoce como la creación de una copia profunda (a diferencia de la copia superficial por defecto). Utilice los siguientes pasos para determinar cómo y cuándo hacer copias profundas en C ++:

  1. Haga siempre una copia en profundidad si el constructor asigna recursos.

    De forma predeterminada, C ++ hace que las llamadas "superficiales" Miembro por miembro de copias de objetos al pasar a funciones o como consecuencia de una cesión. Debe reemplazar los operadores de copia de poca profundidad por defecto con su profundo equivalente copia para cualquier clase que asigna recursos en el constructor. El recurso más común que consigue asignada es la memoria heap que es devuelto por el nuevo operador.

  2. Incluya siempre un destructor de una clase que asigna los recursos.

    Si crea un constructor que asigna recursos, debe crear un destructor que los restaura. Sin excepciones.

  3. Siempre declarar el destructor virtual.

    Un error de principiante común es olvidarse de declarar su destructor virtual. El programa se ejecutará bien hasta que algún programador desprevenido viene y hereda de su clase. El programa todavía parece funcionar, sino porque el destructor de la clase base no podrá ser invocado correctamente, pérdidas de memoria de su programa como un colador hasta que finalmente se estrella. Este problema es difícil de encontrar.

  4. Incluya siempre un constructor de copia para una clase que asigna los recursos.

    El constructor de copia crea una copia correcta del objeto actual mediante la asignación de memoria fuera del montón y copiar el contenido del objeto de origen.

  5. Siempre reemplazar el operador de asignación para una clase que asigna los recursos.

    Los programadores deben ser disuadidos de los operadores predominantes, pero el operador de asignación es una excepción. Usted debe anular el operador de asignación para cualquier clase que asigna recursos en el constructor.

    El operador de asignación debe hacer tres cosas:

  1. Asegúrese de que el objeto de la izquierda y la derecha no son el mismo objeto. En otras palabras, asegúrese de que el programador de aplicaciones no escribió algo así como (a = a). Si lo son, no hacer nada.

  2. Invoque el mismo código que el destructor en el objeto de la izquierda para volver a sus recursos.

  3. Invoque el mismo código que un constructor de copia para hacer una copia en profundidad del objeto de la derecha en el objeto de la mano izquierda.

  • Si usted no puede hacer eso, entonces elimine el constructor de copia y el operador de asignación para que el programa no puede hacer copias de su objeto.

  • Si ni siquiera se puede hacer eso porque el compilador no admite la función de constructor de borrado C ++ 2011, cree un operador constructor de copia y asignación vacía y declararlas protegidas para mantener a otras clases de su uso.




  • » » » » Comenzando con la programación c ++ para dummies