Pregunta

Hace poco estuve en una entrevista para una posición en la C / C ++ es el idioma principal y durante una pregunta que me dijeron que es posible utilizar la viable para determinar qué clase de una jerarquía de un puntero de base realidad tiendas.

Así que si, por ejemplo, usted tiene

    class A  
    {  
    public:  
    A() {}  
    virtual ~A() {}  
    virtual void method1() {}  
    };

    class B : public A  
    {  
    public:  
    B() {}  
    virtual ~B() {}  
    virtual void method1() {}  
    };

y A * pFoo = new B() instantiate, ¿es realmente posible utilizar la viable para determinar si pFoo contiene un puntero a una instancia de A o B?

¿Fue útil?

Solución

Esto es, obviamente, depende de la implementación, pero, en la mayoría de las implementaciones, la representación en memoria de un objeto de clase o A B se iniciará con un puntero a la viable. Se puede ver en este puntero vtable, compararlo con punteros vtable para los objetos que se sabe que es de clase o A B, y determinar la clase del objeto de esa manera.

Para ilustrar (por supuesto, esto es cualquier cosa menos un buen estilo):

A *pFoo=new B(); // pointer to object of unknown class (either A or B)
A a;  // Object known to be of class A
B b;  // Object known to be of class B
void *vptrA=*((void **)&a);  // Pointer to vtable of class A
void *vptrB=*((void **)&b);  // Pointer to vtable of class B
void *vptrFoo=*((void **)pFoo);  // Pointer to vtable of unknown object
if(vptrFoo==vptrA)
    printf("Class A\n");
else
    printf("Class B\n");

Importante: Este es solamente una ilustración de cómo funcionan la mayoría de las implementaciones; además de ser dependiente de la implementación, esta técnica se descompone en presencia de la herencia múltiple. Usted debe no hacer nada como esto en el código de producción; el uso de RTTI en su lugar.

Otros consejos

Sí, es muy posible hacer - dynamic_cast uso. Esta es la pregunta bastante horrible - un poco mejor que uno podría ser "¿Cómo se implementa dynamic_cast?" pero en realidad si se le pide, ya sea en una entrevista que tendría que preguntarse por el nous del entrevistador. Ser una buena, o incluso un gran, programador de C ++ no depende de saber los detalles de implementación nitpicking como este, pero estos son, por supuesto, fáciles preguntas para segundones a preguntar.

Puede acceder vpointer e incluso puede llamar a cualquier método virtual en la clase a través vpointer. Pero recuerda que esto es malo.

Ejemplo:

class A
{
public:
    void f1()
    {
        cout<<"bbb"<<endl;;
    }
    virtual void f2()
    {
        cout<<"ccc"<<endl;;
    }
    virtual void f3()
    {
        cout<<"ddd"<<endl;;
    }
};

y llamada en el principal

A a;

typedef void (__thiscall* foo)();
(*(foo)((void**)(((void**)(&a))[0]))[1])();

Será acceder vpointer y luego irá por el índice y ejecutará el segundo método en el vtable que es f3 ().

Tenga en cuenta también utilizar RTTI como ya se ha sugerido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top