views:

60

answers:

3

For some reason the following doesn't crash like my program does, but I'm pretty sure it's similar in design. For one, the output's not correct. It outputs something similar to:

0x537ff4 5471612

While the main program outputs (nil) for the pointer address.

The key to the problem might be display_ in Drv.

Here's the 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;
}
+1  A: 

This code:

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

first runs the parent class's ctor, with a yet-uninitialized value of display_, then independently sets display_, but, too late to change the parent class. So the pointer held by the parent class will never be set correctly. I guess you need to add a protected setter method (or make the parent-class-held pointer member itself protected).

Alex Martelli
+1  A: 

Your Drv constructor passes the garbage, uninitialized value of Drv::display_ to Generic before initializing it in the constructor body. You can do a couple of things here, my preferred would be:

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

Because it doesn't result in a duplicate field, but you can also have an abstract getLcdText() in Generic, which could be better if you are already using virtual methods.

Simon Buchan
+1  A: 

In the constructor for Drv, when you first call the constructor for Generic display_ is still uninitialized. You don't new the pointer until later.

pythonic metaphor