Duda en C++

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

Duda en C++

Notapor Juanxo » Mar Jun 23, 2009 11:54 pm

Hola a todos. Estoy haciendome un ejemplillo de un pong, en el que estoy aplicando algunos conceptos de polimorfismo y herencia para comprenderlos un poco mejor.

Mi duda es simplemente si hay alguna diferencia entre estas dos declaraciones:

tipo* variable
tipo *variable

EDITO: Tengo otra duda.
Alguien sabe si se puede crear una clase padre y una clase hijo en dos archivos diferentes.
El caso es que yo creo la clase Stick con su .h y su .cpp, creo la clase Enemy, que deriva de Stick (class Enemy : public Stick), incluyo el .h de Stick y me dice que estoy redefiniendo una clase Stick.

Un saludo y Gracias
Juanxo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Geo » Mié Jun 24, 2009 2:49 am

No hay ninguna diferencia entre las dos declaraciones que comentas, se trata más bien de cuestión de "estilo".

Hay quien argumenta que el * junto al nombre de la variable te deja ver claramente que se trata de una "variable de tipo puntero", para otros les parece adecuado el * junto a tipo pues se expresa más claramente que se trata de "un puntero a tipo", en fin, es lo mismo :P.

Sobre lo segundo, por supuesto que es perfectamente posible definir clases en diferentes archivos, en todo caso el problema se deberá a otro detalle, si puedes poner el código para observarlo mejor :).
Lo que por el momento se me ocurre es que estés incluyendo más de una vez la definición de la clase padre en el código, no que la clase hija sea una redefinición, sino que has colocado en el código nuevamente la declaración de la clase padre al hacer el #include "padre.h".
Si este es el caso, para evitarlo, en el .h de la clase padre pon algo como esto al inicio:
Código: Seleccionar todo
#ifndef PADRE
#define PADRE


y esto al final:
Código: Seleccionar todo
#endif

Esto es necesario para cada archivo en que realices definiciones de clases (.h), pues la instrucción #include lo que hace es insertar en el código el archivo que se le indica, por lo que si no se evita, con cada #include "padre.h" incluirías el código dentro del archivo padre.h. Lo que se hace es definir una macro (PADRE) al momento de incluir por primera vez el código, cuando en algún momento se haga una nueva referencia al código, al estar ya definida la macro, el código no se incluirá nuevamente.
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor Juanxo » Mié Jun 24, 2009 12:22 pm

Muchas gracias Geo.

El problema era el que tu comentabas, que al parecer el compilador estaba viendo clases por todos los lados.

He puesto esas directivas y ya funciona correctamente

Gracias
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Juanxo » Lun Jul 20, 2009 7:18 pm

Aprovecho este tema para postear otra duda y no llenar el foro de temas para pequeñas dudas:

Estoy creando una función para que inicie SDL y no tener que escribirla cada vez. Pongo el código y luego comento mi duda:

Código: Seleccionar todo
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include <iostream>

bool init(SDL_Surface** screen, int screen_width, int screen_height, int bpp, Uint32 flags)
{
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) == -1)
    {
        fprintf(stderr, "Unable to load SDL Systems: %s", SDL_GetError());
        return false;
    }

    atexit(SDL_Quit);

    if(TTF_Init() == -1)
    {
        fprintf(stderr, "Unable to load TTF System: %s", SDL_GetError());
        return false;
    }
    atexit(TTF_Quit);

    *screen = SDL_SetVideoMode(screen_width, screen_height, bpp, flags);
    if (screen == NULL)
    {
        fprintf(stderr, "Unable to set the video mode: %s", SDL_GetError());
        return false;
    }

    return true;
}

int main(int argc, char** argv)
{
    SDL_Surface* screen = NULL;
    SDL_Rect rect;
    SDL_Surface* image;
    SDL_Event event;

    if (init(&screen, 640, 480, 32, SDL_SWSURFACE | SDL_DOUBLEBUF))

...


Mi duda es con respecto a screen en la función init.
si declaro el parámetro como SDL_Surface* screen y hago screen = SDL_SetVideo....... fuera de la función me dice que es NULL. No lo entiendo porque es un puntero.
Si hago la que esta puesta o pasando el parámetro como SDL_Surface* &screen, es decir, pasando el parámetro como referencia, no me da ningún problema fuera de la función.

¿Es correcta la forma? (mas bien, ¿es la mejor?). ¿En caso negativo, cual sería la correcta? ¿Por qué no funciona con SDL_Surface* screen?

Gracias de antemano
Juanxo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor endaramiz » Mar Jul 21, 2009 9:30 am

El puntero es "una variable" que contiene una dirección. Como ya sabrás, por defecto los parámetros en C son por copia (la función trabaja con una copia de lo que le entra como parámetro).
Cuando haces "screen = SDL_SetVideoM..." lo que estás haciendo es que "la variable" screen (que es una copia de la screen del main) pase a tener la dirección de la pantalla de SDL.

Seguramente lo que te ha confundido es que si modificas la dirección a la que apunta el puntero, no tienes ningún problema. Ya que lo que haces es modificar directamente la memoria, no una copia de una variable. Ejemplo:
Código: Seleccionar todo
#include <iostream>
using namespace std;

void f(int* n) {
    *n = 5; //modifica la memoria
}

int main() {
    int a = 1;
    int* b = &a;
    cout << *b << endl;
    f(b);
    cout << *b << endl;
}


Sin embargo, lo que tú haces (que no funciona) es algo así:
Código: Seleccionar todo
#include <iostream>
using namespace std;

void f(int* n) {
    int c = 5;
    n = &c; //modifica la copia de "la variable" que le pasas como parametro
}

int main() {
    int a = 1;
    int* b = &a;
    cout << *b << endl;
    f(b);
    cout << *b << endl;
}
Aunque se arregla simplemente pasando el puntero por referencia (&). Mejor que con los dobles punteros (que son obligados en C), ya que el C++ te permite el paso por referencia. No lo desperdicies.

Saludos y espero haberte ayudado ya que con lo de que el tema es un poco lioso y yo que no me explico muy bien...
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor Juanxo » Mar Jul 21, 2009 9:56 am

gracias endaramiz.
Yo lo tenía (SDL_Surface* &screen) pasado por referencia creo, el tema es que eso de ver * y & juntos, me tiraba para atrás.
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Geo » Mié Jul 22, 2009 5:21 am

Estas dos son equivalentes:
Código: Seleccionar todo
bool init(SDL_Surface** screen, int screen_width, int screen_height, int bpp, Uint32 flags);
bool init(SDL_Surface* &screen, int screen_width, int screen_height, int bpp, Uint32 flags);

La segunda te permite "olvidarte" un poco de la sintaxis de punteros y usar screen dentro del código sin tener que desreferenciarla.
El otro problema, ya lo explicó endaramiz :).
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor Juanxo » Jue Jul 23, 2009 3:43 pm

buenas:

Estoy realizando un miniejemplo de billar para aclararme algunas cosas sobre sobrecarga de operadores.

Investigando por ahí, he visto que algunos hacen:

Código: Seleccionar todo
Vector2D& operator + (const Vector2D& rightHandOperator)


y otros hacen:

Código: Seleccionar todo
Vector2D operator + (const Vector2D& leftHandOperator, const Vector2D& rightHandOperator)


Yo creo que el primero es para sentencias del estilo vector1 = vector1 + vector2 y el segundo tiene pinta de ser más para sentencias del estilo vector1 = vector2 + vector3.

¿Estoy en lo cierto? Esque cada uno lo hace de una manera distinta.

Gracias por la ayuda

Juanxo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Juan Carlos » Jue Jul 23, 2009 10:39 pm

Digamos que tenemos 3 vectores de la clase Vector y queremos hacer lo siguiente:
Código: Seleccionar todo
v1 = v2 + v3

Sin embargo, en vez de operadores queremos usar funciones:

Una opcion seria crear una funcion algo asi:
Código: Seleccionar todo
Vector sumar( Vector, Vector )

y entonces obtendriamos:
Código: Seleccionar todo
v1 = sumar(v2, v3)

Otra opcion, ya que estamos usando un lenguaje orientado a objetos es usar un metodo llamado "sumar" dentro de la clase Vector, resultando en:
Código: Seleccionar todo
class Vector {
           ...
           Vector sumar(Vector)
           ...
}

y luego:
Código: Seleccionar todo
v1 = v2.sumar(v3)

Cual es la diferencia o cual es la correcta? Trabajando con un paradigma orientado a objetos, la opcion correcta es la segunda.
Pero entonces, por que existe la primera opcion, la de usar una funcion?

Para atrapar el concepto, te propongo el siguiente ejemplo: se quiere realizar lo siguiente
Código: Seleccionar todo
v1 = v2 * 3

Dado que estamos con objetos, deberiamos usar metodos. Entonces, dentro de la clase Vector ponemos:
Código: Seleccionar todo
class Vector {
           ...
           Vector multiplicar(int)
           ...
}

Entonces resulta en:
Código: Seleccionar todo
v1 = v2.multiplicar(3)

Joya! Pero que pasa si quiero realizar lo siguiente:
Código: Seleccionar todo
v1 = 3 * v2

Ups! El numero 3 es un int y no puedo agregarle un metodo "multiplicar" al numero 3!
Debido a este problema, C++ permite complementar la sobrecarga usando funciones auxiliares fuera de la clase Vector. O sea, deberemos crear una funcion:
Código: Seleccionar todo
Vector multiplicar(int, Vector)

y ahora si se puede multiplicar
Código: Seleccionar todo
v1 = multiplicar(3, v2)

Es por eso que C++ ofrece ambos mecanismos.

Para simplificar el ejemplo, use nombres como "sumar" y "multiplicar", pero el ejemplo tiene una traduccion inmediata a la sintaxis propia de C++, o sea operator+ y operator*.

Saludos
Juan Carlos
 
Mensajes: 97
Registrado: Sab Jul 07, 2007 1:05 pm


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron