2009-10-19 5 views
0

Pour une raison quelconque, les éléments suivants ne se plantent pas comme le fait mon programme, mais je suis à peu près sûr que leur conception est similaire. Pour un, la sortie n'est pas correcte. Il sort quelque chose de similaire à:Instanciation d'objets et de membres d'objets

0x537ff4 5471612 

Alors que le programme principal sort (nil) pour l'adresse du pointeur.

La clé du problème peut être display_ in Drv.

Voici le code:

#include <iostream> 
#include "debug.h" 

class LCDText { 
    public: 
    int rows_; 
    LCDText() { rows_ = 10; }; 
}; 

class Generic { 
    LCDText *lcdText_; 
    public: 
    Generic(LCDText *lcdText) { lcdText_ = lcdText; }; 
    void Setup() { 
     Error("%p %d", lcdText_, lcdText_->rows_); 
    } 
}; 

class Display : public LCDText { 
    Generic *visitor_; 
    public: 
    Display(Generic *visitor) { visitor_ = visitor; }; 
}; 

class Drv : public Generic { 
    Display *display_; 
    public: 
    Drv() : Generic((LCDText *)display_) { 
     display_ = new Display((Generic *)this); 
    }; 
    ~Drv() { delete display_; }; 
}; 

int main() 
{ 
    Drv drv; 
    drv.Setup(); 
    return 0; 
} 

Répondre

2

Ce code:

Drv() : Generic((LCDText *)display_) { 
    display_ = new Display((Generic *)this); 
}; 

premier exécute le cteur de classe parente, avec une valeur encore-uninitialized de display_, puis règle indépendamment display_, mais, trop tard pour changer la classe parent. Ainsi, le pointeur détenu par la classe parente ne sera jamais défini correctement. Je suppose que vous devez ajouter une méthode setter protégée (ou faire en sorte que le membre pointeur de la classe parent soit protégé).

2

Votre constructeur Drv passe la valeur non-initialisée de Drv :: display_ à Generic avant de l'initialiser dans le corps du constructeur. Vous pouvez faire une ou deux choses, mon préféré serait:

class Drv : public Generic { 
    Display* display() { return (Display*)lcdText_; } 
public: 
    Drv() : Generic(new Display(this)) {} 
} 

Parce qu'il ne résulte pas dans un champ en double, mais vous pouvez aussi avoir un résumé getLcdText() en générique, ce qui pourrait être mieux si vous utilisez déjà des méthodes virtuelles.

1

Dans le constructeur de Drv, lorsque vous appelez le constructeur pour Generic display_, vous ne l'avez toujours pas initialisé. Vous ne créez pas le pointeur plus tard.

Questions connexes