实例化一个新对象。不确定这是否正确?

时间:2012-03-24 09:42:49

标签: c++

我有一个这种类型的成员指针:

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)可以实例化。

我有一个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_时,我会收到堆内存运行时错误 - 请参阅注释掉的析构函数代码。

有什么建议吗?

安格斯

2 个答案:

答案 0 :(得分:0)

您的对象构造和用法是正确的和标准的C ++。唯一的问题是您注意到的破坏代码。您正在尝试使用类型的指针 - 这不会起作用,编译器不会让您这样做。析构函数应该像释放内存一样简单:

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

此外,请确保在更改状态时删除以前的状态。即next()函数应如下所示:

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
}

答案 1 :(得分:0)

所提出的课程TestHSM未遵循the rule of three。它缺少复制构造函数和复制赋值运算符,或者是一种禁止它们的方法。

您最好的选择是让其他人为您处理资源管理。例如,使用std::unique_ptrboost::scoped_ptr成员。这些选项中的任何一个都将禁止TestHSM的副本。如果需要复制的能力,则必须手动编写复制构造函数,以及状态的一些虚拟复制机制(即clone()成员函数)。