2012-03-24 136 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()成员函数)。