2010-11-05 6 views
11

Duplicar posibles:
Finding the type of an object in C++C++ polimorfismo: Comprobación de tipo de datos de la clase sub

Hola,
Lo siento si es un duplicado, pero no fue capaz de encontrar respuesta a mi pregunta aquí.
Supongamos que hemos siguiente estructura de clases en C++:

class CPolygon { 
    protected: 
    int width, height; 
    public: 
    void set_values (int a, int b) 
     { width=a; height=b; } 
    }; 

class CRectangle: public CPolygon { 
    public: 
    int area() 
     { return (width * height); } 
    }; 

Ahora tengo un puntero al objeto CPolygon. ¿Cómo puedo comprobar si en realidad es un puntero al objeto de la clase CRectangle?

+5

Como un lado no deberías considerar no hacer eso. Si crees que debes hacerlo, probablemente haya algo mal con tu diseño. –

+1

Es * siempre * es. No es necesario verificar Además, * por favor * no anteponga los nombres de su clase con 'C'. Este fue * nunca * un estilo recomendado y su uso generalizado se basa en un malentendido de las convenciones de nombres de MFC. –

+3

Así no es como funciona el polimorfismo. Polimorfismo significa eliminar la necesidad de verificar esto. – delnan

Respuesta

10

Puede hacer esto comprobando si dynamic_cast<CRectangle*>(ptr) devuelve no nulo, donde ptr es un puntero a CPolygon. Sin embargo, esto requiere que la clase base (CPolygon) tenga al menos una función miembro virtual que probablemente necesite de todos modos (al menos un destructor virtual).

5

Lo ideal es que no. Se utiliza el polimorfismo simplemente hacer lo correcto:

class CPolygon { 
    protected: 
    int width, height; 
    public: 
    void set_values (int a, int b) 
     { width=a; height=b; } 

    virtual int area() const = 0; 
    }; 

class CRectangle: public CPolygon { 
    public: 
    int area() const 
     { return (width * height); } 
    }; 

llamada area() en el puntero CPolygon, y obtendrá la zona por un CRectangle si eso es lo que es. Todo lo que derive de CPolygon tendrá que implementar area() o no podrá instanciarlo.

+8

Eso no es lo que pidió OP, y si bien es fácil decir "simplemente no hagas eso", existen razones válidas para querer obtener el tipo concreto de una clase. –

+0

@McWafflestix: pero ¿y si tengo otra subclase con alguna función extra y quiero llamar a esas funciones? –

+0

@AmitS: ese es mi punto; es posible que desee hacer algo como eso. –

2

Puede realizar un dynamic_cast a CRectangle y ver si eso da un resultado adecuado o no.

3

Usted dynamic_cast que

CRect* pRect = dymanic_cast<CRect*>(MyPolygonPointer); 

if(pRect != 0) 
{ 
    //...it is a CRect 
} 

Pero, naturalmente, downcasting es una mala práctica y debe utilizarse con precaución. En un buen diseño, no le importa el tipo dinámico real del puntero.