Ver Mensaje Individual
  #2 (permalink)  
Antiguo 10/01/2006, 17:19
Avatar de X.Cyclop
X.Cyclop
Usuario baneado!
 
Fecha de Ingreso: diciembre-2005
Ubicación: México, D.F.
Mensajes: 1.328
Antigüedad: 18 años, 4 meses
Puntos: 0
Conversiones explícitas de tipo

Además de las conversiones implícitas de tipo, del lenguaje C, que tienen lugar al realizar operaciones aritméticas entre variables de distinto tipo y en las sentencias de asignación; el lenguaje C++ dispone de otra conversión explícita de tipo con una notación similar a la de las funciones y más sencilla que la del cast. Se utiliza para ello el nombre del tipo al que se desea convertir seguido del valor a convertir entre paréntesis.

Código:
/* Conversión explicita en C */
#include<stdio.h>
main()
{
    double x=2.5;
    int y=(int)(x);
    printf("y tiene x entero: %d",y);
    getchar();
}
Código:
// Conversión explicita en C++
#include<iostream.h>
main()
{
    double x=2.5;
    int y=int(x);
    cout<<"y tiene x entero: "<<y;
    getchar();
}
Sobrecarga de funciones

La sobrecarga (overload) de funciones consiste en declarar y definir varias funciones distintas que tienen un mismo nombre, pero que difieren en cuanto a sus argumentos. En el momento de la ejecución se llama a una u otra función dependiendo del número y/o tipo de los argumentos actuales de la llamada a la función.
La sobrecarga de funciones no permite que se hagan dos funciones con diferente valor de retorno, y con un mismo numero de argumentos. De hecho, el valor de retorno no influye en la determinación de la función que es llamada; sólo influyen el número y tipo de los argumentos.
Tampoco se admite que la diferencia sea el que en una función un argumento se pasa por valor y en otra función ese argumento se pasa por referencia.
La sobrecarga de funciones es algo muy importante, aunque su relevancia se verá mejor en el siguiente ejemplo:

Código:
/* Ejemplo de función que no se puede sobrecargar en C */
#include<stdio.h>
#include<math.h>
double potencia(double x)
{
return pow(x,x);
}
double potencia2(double x,double y)
{
return pow(x,y);
}
main()
{
    double a=2,b=3,r1=0,r2=0;
    r1=potencia(a);
    r2=potencia2(a,b);
    printf("Potencia de %f a la %f = %f",a,a,r1);
    printf("\nPotencia de %f a la %f = %f",a,b,r2);
    getchar();
}
Código:
// Ejemplo de función sobrecargada en C++
#include<iostream>
#include<math.h>
using namespace std;
double potencia(double x)
{
return pow(x,x);
}
double potencia(double x,double y)
{
return pow(x,y);
}
main()
{
    double a=2,b=3,r1=0,r2=0;
    r1=potencia(a);
    r2=potencia(a,b);
    cout<<"Potencia de "<<a<<" a la "<<a<<" = "<<r1
        <<"\nPotencia de "<<a<<" a la "<<b<<" = "<<r2<<endl;
    getchar();
}
Otro ejemplo:

Código:
/* Ejemplo de función que no se puede sobrecargar en C */
#include <stdio.h>
#include <string.h>
void string_copy(char *copia, const char *original)
{
	strcpy(copia, original);
}
/* Se pierde tiempo y claridad declarando otra función
que hace lo mismo, pero recibe diferentes argumentos*/
void string_copy2(char *copia, const char *original, const int longitud)
{
	strncpy(copia, original, longitud);
}
static char string_a[20], string_b[20];
main()
{
	string_copy(string_a, "Aquello");
	string_copy2(string_b, "Esto es una cadena", 4);
	printf("%s y %s\n",string_b,string_a);
	getchar();
}
Código:
// Ejemplo de función sobrecargada en C++
#include <iostream>
#include <string.h>
using namespace std;
void string_copy(char *copia, const char *original)
{
	strcpy(copia, original);
}
void string_copy(char *copia, const char *original, const int longitud)
{
	strncpy(copia, original, longitud);
}
static char string_a[20], string_b[20];
main()
{
	string_copy(string_a, "Aquello");
	string_copy(string_b, "Esto es una cadena", 4);
	cout << string_b << " y " << string_a <<endl;
	getchar();
}
Valores por defecto de parámetros de una función

En C se espera encontrar una correspondencia exacta entre la lista de argumentos actuales (llamada) y la lista de argumentos formales (declaración y definición) de una función o método.
En C++ la situación es diferente pues se pueden definir valores por defecto para todos o algunos de los argumentos formales. Después, en la llamada, en el caso de que algún argumento esté ausente de la lista de argumentos actuales, se toma el valor asignado por defecto a ese argumento. Por ejemplo, en este caso se asigna a uno de los valores de la función, el valor por defecto 2, lo cual permite que se pueda invocar esta función con un solo valor:

Código:
// Valores por defecto en C++
#include<iostream>
#include<math.h>
using namespace std;
double potencia(double x,double y=2)
{
return pow(x,y);
}
main()
{
    double a=2,b=3,r1=0,r2=0;
    //esto generaría errores en C
    r1=potencia(a);
    r2=potencia(a,b);
    cout<<"Potencia de "<<a<<" a la "<<a<<" = "<<r1
        <<"\nPotencia de "<<a<<" a la "<<b<<" = "<<r2<<endl;
    getchar();
}
Variables de tipo referencia

Para un mayor entendimiento de esta modificación se presentará, de una vez, la manera en que se pasaban argumentos por referencia en C; y luego aclararemos lo nuevo del C++ (incluyendo el código respectivo). Para ello se va a utilizar la función permutar():

Código:
/* Variables por referencia en C */
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
int i = 1, j = 2;
void permutar(int *a, int *b);
printf("\ni = %d, j = %d", i, j);
permutar(&i, &j);
printf("\ni = %d, j = %d", i, j);
}
void permutar(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
La cuestión, en C, para pasar parámetros por referencia está en el uso de punteros. Al pasar la dirección de la variable, ésta es accesible desde dentro de la función y su valor puede ser modificado. De igual manera, si dentro de una función hay que modificar un puntero habrá que pasar su dirección como argumento, esto es, habrá que pasar un puntero a otro puntero.

C++ ofrece una nueva forma de pasar argumentos por referencia a una función, en donde no es necesario utilizar (dentro de la función) el operador indirección (*) para acceder al valor de la variable que se quiere modificar.

Esto se hace mediante de un nuevo tipo de dato (que no existe en C) llamado tipo referencia. Las variables referencia se declaran por medio del carácter ámpersan (&). Por lo demás, son variables normales que contienen un valor numérico o alfanumérico. El ejemplo anterior convertido a C++ es el siguiente:

Código:
//  Variables por referencia en C++
#include <iostream>
#include <stdlib.h>
using namespace std;
main()
{
    int i = 1, j = 2;
    void permutar(int &a, int &b); // los argumentos son referencias
    cout<<"\ni = "<<i<<", j = "<<j;
    permutar(i,j); // los argumentos no llevan (*) ni (&)
    cout<<"\ni = "<<i<<", j = "<<j;
    getchar();
}
void permutar(int &a, int &b) // los argumentos son referencias
{
    int temp;
    temp = a; // no hace falta utilizar
    a = b; // el operador indirección (*)
    b = temp;
}
Los dos programas dan idéntico resultado, pero el de C++ tiene una ventaja: no hay que utilizar el operador indirección dentro de la función permutar(). C++ permite pasar argumentos por referencia sin más que anteponer el carácter (&) a los argumentos correspondientes, tanto en el prototipo como en el encabezamiento de la definición. Cuando se invoca esta función los argumentos se ponen directamente, sin anteponerles ningún carácter u operador.
En C++ existe realmente un tipo llamado referencia que va más allá del paso de argumentos a funciones. Las variables de tipo referencia se declaran con el operador (&) y deben ser inicializadas a otra variable o a un valor numérico. Por ejemplo:

int i=2;
int& iref = i; // declaración de referencia válida

Donde la variable i en una variable entera normal, y la variable por referencia iref es un especie de alias que representa esa variable. Entonces, si se modifica, por ejemplo, la variable i, también se modifica la variable iref, y viceversa. La diferencia con un puntero es que si ya se declaró una variable por referencia a una variable, no puede ser re-asignada para referenciar a otra variable. El principal uso de las variables referencia es como valor de retorno o argumentos de funciones. Pero, ¿para que puede ser útil esto?, considérese el siguiente ejemplo; se desea que se evalúen dos valores, y que al mayor valor se le asigne el numero 0, utilizando una función para dicho propósito:

Código:
//Referencias en funciones en C++
#include <iostream>
#include <stdlib.h>
using namespace std;
main()
{
    int i = 10, j = 8;
    int maxref(int &a, int &b); // los argumentos son referencias
    cout<<"\ni = "<<i<<", j = "<<j;
    //Esto es muy inusual en cuanto a invocación de variables
    //Pero en C++ no genera errores
    maxref(i,j)=0;
    cout<<"\ni = "<<i<<", j = "<<j;
    getchar();
}
int& maxref(int& a, int& b)
{
    if (a >= b)
    return a;
    else
    return b;
}

En este ejemplo se asigna 0 al alias de un valor mayor. Este mismo efecto puede conseguirse mediante punteros, pero con referencias resulta mucho más sencillo.