3

最近質問を投稿しましたが、私がひどく間違っていると指摘されました!

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

状態クラス (これらの多くが存在する可能性があります):

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

3 に答える 3

4

あなたが抱えている問題は、状態の動作と状態マシンの動作を混同していることだと思います。つまり、状態動作の実行と状態変化の管理です。それらは別々に保管する必要があります。

ステートマシン全体を表すクラスを持つことができます。内部に状態固有の機能はありません。代わりに、現在の状態オブジェクトへのポインターが含まれます。(個々の状態クラスはすべて、共通の基本クラスから派生していると想定しています。)

状態を変更する場合、ステート マシン クラスは古い状態を削除し、新しい状態を作成および/または保存します。個々の状態クラスは、状態マシンで関数を呼び出して変更を開始することはできますが、それを直接行うべきではありません。

補足として、使用しないことをお勧めしdelete thisます。技術的には機能しますが、通常は良い考えではありません。

于 2013-10-30T15:57:19.123 に答える
1

あなたの場合、あなたはすべきではありません

delete this;
_state = new_state;

次のようにして、 new_state の値をこれに割り当てるだけです。

*this = *new_state

しかし、これは良いデザインではないと思います。このを確認してください。

于 2013-10-30T15:58:28.550 に答える