2012-03-24 93 views
0

我有一個成員指針與這種類型的:實例化一個新對象。不確定這是否正確?

const TopState<TestHSM>* state_; 

state_是多態型的。

TopState是基:

template<typename H> 
struct TopState { 
//... functions etc 
}; 

有一個位的層級的最後LeafState這是不抽象:

template<typename H, unsigned id, 
typename B=CompState<H,0,TopState<H> > > 
struct LeafState : B { 
    //...functions 
    static const LeafState obj; 
}; 

以下對象表示狀態:

//indentation to indicate state nesting 
typedef CompState<TestHSM,0>  Top; 
typedef CompState<TestHSM,1,Top> S0; 
typedef CompState<TestHSM,2,S0>  S1; 
typedef LeafState<TestHSM,3,S1>   S11; 
typedef CompState<TestHSM,4,S0>  S2; 
typedef CompState<TestHSM,5,S2>   S21; 
typedef LeafState<TestHSM,6,S21>   S211; 

只能注意S11S211LeafState's)可以被實例化。

我有一個TestHSM類,看起來像這樣:

class TestHSM { 
public: 
TestHSM() { 
    state_ = new S11; 
} 

//fix destruction - problem 
~TestHSM() { 
    //reset to s11 
// state_ = &S11; 
// delete state_; 
// state_ = 0; 
} 

void next(const TopState<TestHSM>& state) 
{ 
    state_ = &state; 
} 

private: 
const TopState<TestHSM>* state_; 
}; 

我的問題,現在是state_對象的創建。參見上面的構造函數。這有效,但我不完全確定它是否是正確的做事方式?

S11是第一個可以實例化對象的狀態 - 在我的程序S11是啓動時的第一個狀態。代碼「按預期工作」。無論如何還是好像。但我不確定這是否是最佳或甚至正確的方式來安撫第一個國家?

此外,如果我這樣做,那麼當我嘗試刪除state_時,會出現堆內存運行時錯誤 - 請參閱註釋析構函數代碼。

有什麼建議嗎?

安格斯

+0

你可以使代碼最小? – 2012-03-24 09:44:34

回答

0

您的對象的構造和使用是正確的和標準的C++。當你注意到唯一的問題是你的銷燬代碼。你正試圖獲得一個類型的指針 - 這不會起作用,編譯器不會讓你這樣做。析構函數應儘可能釋放內存一樣簡單:

~TestHSM() { 
    if (state_) { 
    delete state_; 
    state_ = 0; 
    } 
} 

而且,當你改變狀態,以刪除以前的狀態確定。即下一個()函數應該是這樣的:

void next(TopState<TestHSM> *state) 
{ 
    if (state_) 
     delete state_; 
    state_ = state; 
} 

你應該使用new構建的狀態總是傳遞到下一個功能,讓TestHSM免費當它是沒有必要:

int main() { 
    TestHSM test; 
    test.next(new S211()); 
    // No freeing, TestHSM destructor frees everything 
} 
0

提出該類TestHSM沒有跟隨the rule of three。它缺少拷貝構造函數和拷貝賦值操作符,或者禁止它們的方法。

你最好的選擇是讓其他人爲你處理資源管理。例如,使用std::unique_ptrboost::scoped_ptr成員。這些選項中的任何一個都將禁止TestHSM的副本。如果需要進行復制的能力,則必須手動編寫複製構造函數,併爲這些狀態創建一些虛擬複製機制(即clone()成員函數)。

相關問題