4

重複の可能性:
C++: これを削除しますか?

ゲームの状態を管理するシステムを作成しようとしています。

現在の設計の問題は、状態を切り替えると、制御が新しい状態に切り替わる前に古い状態が削除されることです。

以下は、私のコードの簡略版です。

class StateManager;

class State
{
public:
    virtual void update(StateManager &manager)= 0;
    virtual ~State(){}
};


class StateManager
{
public:
    void setState(std::unique_ptr<State> && newState )
    {
        currentState = std::move(newState);
    }
    std::unique_ptr<State> currentState;

    void run()
    {
        currentState->update(*this);
    }
};

State オブジェクトが update メソッド内で StateManager::setState を呼び出すと、破棄されたばかりのオブジェクトでメンバー関数が呼び出される期間が発生することに注意してください。

この動作の完全な例はhttp://ideone.com/WHLzJLにあります。FirstState::update が返される前に、FirstState のデストラクタがどのように呼び出されるかに注意してください。

これは C++ で未定義の動作ですか? その場合、どのようにデザインを変更すればよいですか?

4

3 に答える 3

7

いいえ、気をつけていれば大丈夫です: https://isocpp.org/wiki/faq/freestore-mgmt#delete-this

于 2012-11-02T23:10:00.457 に答える
2

長い間問題はなく、関数で行う最後のことです。(は一般的なイディオムです。) ただし、この特定のケースでは、一般的には new を返すdelete this方が望ましいことがわかりました(これは である可能性があります)。それを呼び出すコードは、それをポインタに割り当てるだけです。 State::updateStatethisStateManager

この場合、スマート ポインターのセマンティクスに注意してください。侵略的な共有ポインターを使用してそれを行いましたが、現在のスマート ポインターのほとんどはここで失敗すると思われます。一方、ここではスマート ポインターは実際には必要ありません。

于 2012-11-02T23:21:30.160 に答える
0

私の知る限り、主な効果はthisダングリング ポインターになることです。そのため、フィールドへのアクセス、メソッドの呼び出し、または実行時の型情報に依存するvirtualようなことを行うと、未定義の動作が発生します。dynamic_cast<T*>(this)

于 2012-11-02T23:12:16.847 に答える