2009-10-19 115 views
0

出於某種原因,以下內容不會像我的程序那樣崩潰,但我很肯定它在設計上類似。首先,輸出不正確。它輸出類似於:實例化對象和對象成員

0x537ff4 5471612 

雖然主程序輸出(nil)指針地址。

問題的關鍵可能是Dr_中的display_。

下面的代碼:

#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; 
} 

回答

2

此代碼:

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

首先運行父類的構造函數,用display_一個尚未初始化值,然後獨立設置display_,但爲時已晚改變父類。所以父類所持有的指針永遠不會被正確設置。我想你需要添加一個受保護的setter方法(或者讓父類持有的指針成員本身受保護)。

2

您的Drv構造函數在構造函數體中初始化它之前將Drv :: display_的未初始化值傳遞給Generic。你可以做幾件事情在這裏,我的首選是:

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

因爲它不會導致重複字段,但你也可以在通用的抽象getLcdText(),這可能是更好的,如果你已經在使用虛擬方法了。

1

在Drv的構造函數中,當您第一次調用Generic display_的構造函數時,仍然未初始化。稍後您不會新建指針。