2013-10-30 108 views
2

我最近发表了一个问题,有人指出我会犯错!如何安全地更改状态对象之间的状态?

main()我正在做一个状态,然后将整数传递给processState()并基于整数它将改变状态(通过销毁状态并创建一个新状态的新实例),或保持不变州。

我指出的主要问题是函数void state_t::changeState(state_t * new_state)。我删除了“this”,然后指向已删除的“_state”指针指向新的状态......现在,我指出,这显然是一件坏事。

所以问题是:使用不同状态实现这种状态切换的最佳方式是什么?也许_state需要是一个全局指针指向当前状态还是一些这样的?

Main.cpp的:

#include <QCoreApplication> 
#include <QDebug> 
#include "statemachine.h" 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    state_t *myState = new testState1(); 

    myState = myState->processState(1); 
    myState = myState->processState(2); 
    myState = myState->processState(3); 
    myState = myState->processState(1); 

    return a.exec(); 
} 

基本类型:

#include "state_t.h" 

state_t::state_t(QByteArray stateName) : 
    name(stateName), 
    _state(this) 
{ 
    qDebug() << this->name << ": Creating state"; 
} 

state_t::~state_t() 
{ 
    qDebug() << this->name << ": Deleting state"; 
    qDebug() << endl; 
} 

void state_t::changeState(state_t * new_state) 
{ 
    // Check if the state has changed 
    if (this != new_state) 
    { 
     qDebug() << this->name << ": State changed to: " << new_state->name; 
     delete this; 
     _state = new_state; 
    } 
    else 
    { 
     qDebug() << this->name << ": State un-changed"; 
    } 
} 

void state_t::unknownStateEventHandler(int event) 
{ 
    qWarning() << this->name << ": Unknown event " << event; 
} 

State类(可以有很多这样的):

#include "teststate1.h" 

testState1::testState1() : 
    state_t("state1") 
{ 
} 

state_t *testState1::processState(int event) 
{ 
    qDebug() << name << ": event" << event; 
    switch (event) 
    { 
     case 2: 
     { 
      changeState(new testState2()); 
      //changeState_t(testState2); 
      break; 
     } 
     default: 
     { 
      unknownStateEventHandler(event); 
      break; 
     } 
    } 

    return _state; 
} 
+0

@ScarletAmaranth:这是“所有的冰雹”。我们都会感激人们大喊大叫的时代结束了。 ;) – thokra

+0

@thokra这是一个不愉快的拼写失败,谢谢你,我刚刚删除了评论:) – ScarletAmaranth

+0

@thokra&Scarlet ... lol :) –

回答

2

我认为这个问题你”我们得到的结果是,你正在混合状态机的行为与状态机的行为;即执行状态行为与管理状态更改。这些应该保持分开。

你可以有一个类来代表你的状态机作为一个整体。它没有任何状态特定的功能。相反,它将包含一个指向当前状态对象的指针。 (我假设你的所有状态类都是从一个公共基类派生的)。

当你想改变状态时,状态机类将删除旧状态并创建和/或存储新状态。各个状态类不应该直接这样做,尽管他们可以在状态机上调用一个函数来启动更改。

作为一个方面说明,最好避免使用delete this。它在技术上可行,但通常不是一个好主意。

+1

实例自杀应该,如果有的话,应该非常谨慎。 – thokra

+0

谢谢,这是有道理的:) –

0

在你的情况,你不应该叫

`删除;

_STATE = NEW_STATE;`

你应该只由NEW_STATE的值赋给这个:

*this = *new_state 

但我不认为这是一个不错的设计。请检查这个example

+0

我看到你想说什么,但在我的情况下,这并没有达到目标,因为我特别想删除“旧/当前”状态,然后实例化新的。链接是,但是非常有用:) –