elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
28 Mayo 2012, 23:28  


Tema destacado: Recuperar cuenta de Google, GMail, Youtube

+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  ayuda (polimorfismo,funciones amigas y metodos virtuales)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ayuda (polimorfismo,funciones amigas y metodos virtuales)  (Leído 824 veces)
fredx

Desconectado Desconectado

Mensajes: 5



Ver Perfil
ayuda (polimorfismo,funciones amigas y metodos virtuales)
« en: 9 Noviembre 2008, 23:18 »

 :huh:
Alguien me podría mostrar un ejemplo de un programa en c++ completo que contenga funciones amigas , funciones virtuales y polimorfismo es para entender como funciona ya que no entiendo muy bien eso temas.

Gracias.


En línea
agente_naranja


Desconectado Desconectado

Mensajes: 483



Ver Perfil
Re: ayuda (polimorfismo,funciones amigas y metodos virtuales)
« Respuesta #1 en: 10 Noviembre 2008, 14:14 »

Sólo se dos de esas cosas:

FUNCIONES AMIGAS:

Son aquellas que te permiten acceder a partes privadas de una clase sin necesidad de ser declaradas dentro de la clase.

Un intento de acceso a un dato privado de una clase te dará error:

Código
#include <iomanip>
class Ensayo
{
public:
Ensayo();
int datos_public;
private:
int datos_private;
};
Ensayo::Ensayo(){
datos_public = 10;
datos_private = 25;
}
int main(){
 
Ensayo objeto();
cout << "Datos publicos: " << Ensayo.datos_public << '\n';
cout << "Datos privados: " << Ensayo.datos_private << '\n'; // LINEA PROBLEMATICA
 
return EXIT_SUCCESS;
}
 

Este código veras que intenta acceder a la parte privada de la clase, datos_private. No te compilará, te dará un error como:

Citar
C:\Dev-Cpp\programas\temporal.cpp||In function `int main()':|
C:\Dev-Cpp\programas\temporal.cpp|43|error: `int Ensayo::datos_private' is private|
C:\Dev-Cpp\programas\temporal.cpp|54|error: within this context|
||=== Build finished: 2 errors, 0 warnings ===|

Ahora, creemos lo siguiente: Una función externa con la cual podamos acceder a los datos internos de la clase, sin necesidad de hacerla parte de la clase.

Código
#include <iostream>
class Ensayo
{
friend int amiga( Ensayo & ); // CREAMOS UNA FUNCION , LE AGREGAMOS "FRIEND" AL INICIO.
public:
Ensayo( void );
int datos_public;
private:
int datos_private;
};
Ensayo::Ensayo( void ){
datos_public = 10;
datos_private = 25;
}
// LA FUNCION AMIGA ESTA DENTRO DEL MARCO GLOBAL, NO DEBO ANTEPONER "Ensayo::" A SU DECLARACION.
int amiga ( Ensayo & objeto ){
return objeto.datos_private;
}
int main(){
 
Ensayo objeto;
 
std::cout << "Datos publicos: " << objeto.datos_public << '\n';
std::cout << "Datos privados: " << amiga(objeto) << '\n';
 
return EXIT_SUCCESS;
}

Lo que hicimos fue, dentro de la clase, crear una función amiga() que recibe como parámetro cualquier objeto de tipo Ensayo, y devuelve su parte privada. De esta manera tenemos una clase que nos permite leer la parte privada de la clase, sin necesidad de hacerla miembro de la clase.

POLIMORFISMO

Polimorfismo es la capacidad de declarar una funcion con más de una serie de parámetros distinto.
Por ejemplo, imaginate como funciona el operador de salida "cout" en C++. A veces tu le pasas un entero, otras veces un float, otras una cadena, ¿cómo hace para saber como debe procesar cada valor? Pues muy simple, hay toda una lista de funciones declaradas para cada uno de estos valores.

Digamos que tu tienes una funcion llamada "imprimir"; y quieres que, al pasarle un entero como parametro, esta funcion imprima "Tu numero es tal", y que en cambio, al pasarle una cadena, te imprima "Has dicho la frase tal". Para esto, lo único que debes hacer es crear dos funciones con una lista de parámetros diferente.


Código
#include <iostream>
#include <string>
using std::string;
using std::cout;
 
void imprimir ( int a ){
cout << "Has dicho el numero " << a << '\n';
}
void imprimir ( string f ){
cout << "Has dicho la frase " << f << '\n';
}
 
int main(){
 
int numero = 17;
string frase = "Bienvenido a casa";
 
imprimir(numero);
imprimir(frase);
 
return EXIT_SUCCESS;
}

La salida es:

Citar
Has dicho el numero 17
Has dicho la frase Bienvenido a casa

¿Ves? Las dos funciones se llaman igual, pero según el parámetro que le pases, actuará una o la otra. Si le pasas un entero, actuará la primera, y si le pasas una cadena, actuará la segunda.

Si tienes dudas, o quieres más ejemplos, no dudes en preguntar ;)



En línea

ҒrεακΠιи∂

Desconectado Desconectado

Mensajes: 184



Ver Perfil
Re: ayuda (polimorfismo,funciones amigas y metodos virtuales)
« Respuesta #2 en: 10 Noviembre 2008, 14:39 »

Buenas

agente_naranja, tenes errado el concepto de polimorfismo.

Polimorfismo es la habilidad de los objetos de responder al mismo mensaje. Lo que tu definiste es sobrecarga.


Salu2 FreakMind
En línea

Connoisseurs of C semantics find C++ inferior to ++C
agente_naranja


Desconectado Desconectado

Mensajes: 483



Ver Perfil
Re: ayuda (polimorfismo,funciones amigas y metodos virtuales)
« Respuesta #3 en: 10 Noviembre 2008, 15:22 »

Ja ja, tienes razón Freak. Vaya error de conceptos :P
En línea

Anibal784


Desconectado Desconectado

Mensajes: 762

Yo no la vote, pero me la tengo que aguantar igual


Ver Perfil WWW
Re: ayuda (polimorfismo,funciones amigas y metodos virtuales)
« Respuesta #4 en: 11 Noviembre 2008, 12:48 »

Tal como definió  ҒrεακΠιи∂, "Polimorfismo es la habilidad de los objetos de responder al mismo mensaje", el polimorfismo y las funciones virtuales están muy ligadas en C++, las funciones virtuales es lo que permite que exista polimorfismo en C++, ejemplo:
Código
#include <iostream>
 
class A {
public:
   void a(){
       std::cout << "Hola soy A\n";
   }
};
 
class B : public A{
public:
   void a() {
       std::cout << "Soy b\n";
   }
};
 
int main (){
   A *a = new B;
 
   a->a();
}
 
éste código imprime "Soy a", esto es porque el compilador guarda información de que el objeto es A (aunque yo en el programa haga un new de B) y la función que se ejecuta es la que está definida en B. Éste no es el comportamiento desceado, es por eso que si yo le agrego virtual a la función (creo que debería decir mensaje) a() quedando

Código
#include <iostream>
 
class A {
public:
   virtual void a(){
       std::cout << "Hola soy A\n";
   }
};
 
class B : public A{
public:
   void a() {
       std::cout << "Soy b\n";
   }
};
 
int main (){
   A *a = new B;
 
   a->a();
}
 
Ahí si funciona, todo eso es porque la palabra reservada virtual le indica al compilador que esa es una función "heredable", por así decirlo, que sus clases hijas pueden reimplementar. Buscá thinking in C++ (está en español y se puede descargar gratuitamente de la red) que explica muy bien cómo maneja C++ el polimorfismo.
En línea

El que llega sin que lo llamen, se va sin que lo echen.

Citar
Vos no la votaste por eso la tenes adentro.
Lo fino no es lo tuyo, y a mi me chupa un huevo, soy argentino y no peronista, y eso es lo que realmente te molesta.
ҒrεακΠιи∂

Desconectado Desconectado

Mensajes: 184



Ver Perfil
Re: ayuda (polimorfismo,funciones amigas y metodos virtuales)
« Respuesta #5 en: 11 Noviembre 2008, 13:11 »

Buenas

Lamento decirte que tambien estas errado Anibal784. Los metodos virtuales no es lo que posibilitan el polimorfismo.

Aca les dejo un codigo de muestra.
Código
#include <iostream>
#include <cstdlib>
 
class claseA
{
public:
void print() {
std::cout << "-- Soy de clase A --" << std::endl;
}
 
virtual void print2() {
std::cout << "-- Soy de clase A --" << std::endl;
}
};
 
class claseC : public claseA
{
public:
void print() {
std::cout << "-- Soy de clase C --" << std::endl;
}
 
void print2() {
std::cout << "-- Soy de clase C --" << std::endl;
}
 
};
 
class claseB
{
public:
void print() {
std::cout << "-- Soy de clase B --" << std::endl;
}
};
 
void xprint(claseA *);
void xprint2(claseA *);
 
int main(void)
{
claseA    a;
claseB  b;
claseC    c;
std::cout << "Polimorfismo" << std::endl;
a.print();
b.print();
c.print();
std::cout << "----------------------------------" << std::endl;
std::cout << "Funciones virtuales" << std::endl;
std::cout << "Sin virtual" << std::endl;
xprint(&a);
xprint(&c);
std::cout << "Con virtual" << std::endl;
xprint2(&a);
xprint2(&c);
 
system("pause");
return 0;
}
 
void xprint(claseA *clase)
{
clase->print();
}
 
void xprint2(claseA *clase)
{
clase->print2();
}

A ver quien dice que posibilita las funciones virtuales...


Salu2, FreakMind
En línea

Connoisseurs of C semantics find C++ inferior to ++C
Anibal784


Desconectado Desconectado

Mensajes: 762

Yo no la vote, pero me la tengo que aguantar igual


Ver Perfil WWW
Re: ayuda (polimorfismo,funciones amigas y metodos virtuales)
« Respuesta #6 en: 11 Noviembre 2008, 13:59 »

Es hilar muy fino y depender de C++, lo que vos querés decir es que b tiene un método del mismo nombre (print) que tiene a y c pero que responde diferente. No está mal, pero de qué te sirve, tu ejemplo sería más un ejemplo de sobrecarga más que de polimorfismo. También está mal ya que claseC no responde bien al método print en la función xprint(), mientras que si lo hace a la función xprint2(), por qué, porque print2 es virtual.

    Por qué digo que es hilar muy fino, porque yo no puedo usar tu función print de claseB en una función genérica, bien como hacés en xprint() y xprint2(). Es más bien sobrecarga, porque el compilador transforma esa función en una llamada print(claseB obj), otra que me acordé ahora el polimorfismo es en tiempo de ejecución, mientras que esas llamadas son en tiempo de compilación, fijate vos que cuando en tu código hacés:
Código
claseA a;
claseB b;
claseC c;
 
a.print();
b.print();
c.print();
 
no es polimorfismo, ni siquiera en c, pero en la función xprint2() si, porque es el programa en tiempo de ejecución que se fija y dice, "ah, yo recibo un objeto de claseA, pero me llegó un claseC, me tengo que fijar en la tabla virtual a ver dónde está esa función" y comienza todo el proceso de búsqueda.

PD: lo bueno es leer y el que más me gusta como lo explica es:
Thinking in C++ capitulo 6
Thinking in C++ capitulo 15
« Última modificación: 11 Noviembre 2008, 14:01 por Anibal784 » En línea

El que llega sin que lo llamen, se va sin que lo echen.

Citar
Vos no la votaste por eso la tenes adentro.
Lo fino no es lo tuyo, y a mi me chupa un huevo, soy argentino y no peronista, y eso es lo que realmente te molesta.
ҒrεακΠιи∂

Desconectado Desconectado

Mensajes: 184



Ver Perfil
Re: ayuda (polimorfismo,funciones amigas y metodos virtuales)
« Respuesta #7 en: 11 Noviembre 2008, 14:43 »

Buenas

Es hilar muy fino y depender de C++,
No creo que sea hilar tan fino, y digamos que si estamos programando en C++, dependemos de C++ :P

lo que vos querés decir es que b tiene un método del mismo nombre (print) que tiene a y c pero que responde diferente.
No solo el mismo nombre. claseA, claseB y claseC tienen el metodo print con la misma FIRMA (eso si mal no recuerdo incluye ademas del nombre, el valor de retorno y parametros).

No está mal, pero de qué te sirve, tu ejemplo sería más un ejemplo de sobrecarga más que de polimorfismo.
Sobrecarga hubiera sido si le hubiera agregado algun parametro a print o le hubiera cambiado el valor de retorno

También está mal ya que claseC no responde bien al método print en la función xprint(), mientras que si lo hace a la función xprint2(), por qué, porque print2 es virtual.
No esta mal, justamente lo hice para que vean esa diferencia.

Por qué digo que es hilar muy fino, porque yo no puedo usar tu función print de claseB en una función genérica, bien como hacés en xprint() y xprint2().
Obvio que no podes usar xprint y xprint2 con claseB. Estas funciones esperan un claseA *. Si queres usar esos metodos tambien con claseB, tenes que usar Templates

Es más bien sobrecarga, porque el compilador transforma esa función en una llamada print(claseB obj),
Ya respondi arriba esto.

otra que me acordé ahora el polimorfismo es en tiempo de ejecución, mientras que esas llamadas son en tiempo de compilación,
Polimorfismo no implica tiempo sino la capacidad de 2 o mas objetos de responder a un mismo mensaje.

fijate vos que cuando en tu código hacés:
Código
claseA a;
claseB b;
claseC c;
 
a.print();
b.print();
c.print();
 
no es polimorfismo, ni siquiera en c,
Para hacer algo parecido a polimorfismo tenes que hacer bastante trabajo en C jeje.

pero en la función xprint2() si, porque es el programa en tiempo de ejecución que se fija y dice, "ah, yo recibo un objeto de claseA, pero me llegó un claseC, me tengo que fijar en la tabla virtual a ver dónde está esa función" y comienza todo el proceso de búsqueda.
Justamente, eso que explicaste es lo que posibilita las funciones virtual que no es polimorfismo sino algo llamado "binding dinamico"

Salu2, FreakMind
En línea

Connoisseurs of C semantics find C++ inferior to ++C
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines