2009-09-30 13 views
6

tengo las siguientes clases:C++ llamada a un método virtual en clase hija

class A { 
protected: 
    A *inner; 
public: 
    .... 
    virtual void doSomething() = 0; 
    .... 
} 

class B: public A { 
    ... 
    void doSomething() { 
     if(inner != NULL) 
      inner->doSomething(); 
    } 
    ... 
} 

cuando uso inner->doSomething() consigo un fallo de segmentación. ¿Qué debo hacer para llamar al inner->doSomething() en la clase B?

gracias de antemano.

+3

Si obtiene un segfault al usar inner, es probable que sea porque no apunta a un objeto válido. ¿Cómo se inicializa internamente en B? –

+0

¿Cada A contiene un A *? De Verdad? ¿Por qué? –

+0

Ok, se miran el uno al otro. Solo quería comprobar. –

Respuesta

9

Sin una inicialización explícita del miembro interno, es posible que no sea NULO y señale a la memoria no válida. ¿Puede mostrarnos el código que explícitamente interioriza el interior?

Un constructor apropiado para A sería la siguiente

protected: 
A() : inner(NULL) { 
    ... 
} 
+1

Alternativa a la sugerencia de JaredPar, en el constructor, especifique que inner = NULL. Inserte un punto de interrupción en doSomething de la subclase() y observe el valor de inner? – Calyth

+2

no lo estaba inicializando, ya que esperaba que sería NULL y la instrucción if falsa. No sabía que sería posible que un objeto no sea NULO y señale a la memoria no válida. Acabo de hacer inner = NULL en el construtor de B y resolví el problema. muchas gracias. – marcosbeirigo

+2

CUIDADO: para todos los tipos estándar (punteros, int, flotante, etc., también llamados tipos incorporados), la variable no se inicializa cuando se construye (no hay 'Constructores predeterminados'). Como 'inner' es un atributo de A, es responsabilidad del constructor de A inicializarlo, de lo contrario tendrás el problema con cada clase de niño ... –

4

aunque si se asigna la A * a ser el mismo que el B inicializado este puntero que obtendrá un desbordamiento de pila ... algún motivo usted Necesito lo interno? ¿No puedes simplemente llamar a A :: DoSomething()?

Cuestiones relacionadas