2

内部状態オブジェクトを照会するクラスがあります。

class State {...}; //Has a copy and move constructor
class Processor
{
private:
    std::unique_ptr<State> state;

public:
    void process(...)
    {
        State newState;
        ... //create this new state
        state.reset(new State(newState));
    }

    State getState()
    {
        return std::move(*state.release());
    }
};

これは適切な使用法std::moveですか?getStateへの呼び出しごとに1回だけ呼び出されることを保証できますが、この特定のシステムの設計のため、からprocess戻ることはできません。Stack Overflowやその他の場所に関する他の回答の多くは、コンパイラがオブジェクトを移動するか、可能であればRVOするため、オブジェクトを返す方がよいと述べていますが、返されたオブジェクトが関数に対してローカルである場合はすべてでした。 。newStateprocess

状態オブジェクトがunique_ptrの背後にある必要は必ずしもありませんが、それは新しい状態オブジェクトを管理するための最も簡単な方法のように思えました。私の実際の実装では、最後にunique_ptrに直接転送されるポインターがあります。

4

3 に答える 3

1

元のデモ コードにはバグがあることが判明しました。unique_ptr はポインターを決して解放しません。答えは、ローカル関数空間に移動てから正常に戻ることです。

class State {...}; //Has a copy and move constructor
class Processor
{
private:
    std::unique_ptr<State> state;

public:
    void process(...)
    {
        State* newState;
        ... //newState is allocated on the heap somehow
        state.reset(newState);
    }

    State getState()
    {
        State _state(std::move(*state));
        //Optionally: state.reset();
        return _state;
    }
};
于 2013-01-30T22:36:57.860 に答える
0

stateタイプが である を返すだけstd::unique_ptr<State>で、 で完全に移動しstd::move(state)ます。この場合、stateオブジェクトが値によって返されたときにオブジェクト全体をコピーする必要はありません。また、stateオブジェクトが呼び出し元によってキャプチャされない場合、オブジェクトは自動的に破棄されます。これは、複雑なヒープ割り当てオブジェクトに対する非常に効率的なアプローチです。ただし、移動するとオブジェクトstateの状態がクリアされることに注意してください。Processorしたがって、getStateこの場合、 は最適な名前ではなく、fetchStateまたはのようにする必要がありますpopState

于 2013-01-30T23:15:10.803 に答える
0

状態を返すだけで何が問題なのですか

struct state {};
class processor {
public:
  void process() {
    state_ = State();
  }

  state get_state() {
    return std::move(state_);
  }

private:
  state state_;
};

optionalこれにより、プロセッサの構築時に state_ がデフォルトで構築されますが、ラッパーを使用してこれを防ぐことができます。get_stateが呼び出された後にのみ呼び出されることを保証する必要がありますがprocess、これはまったくひどいことです。

于 2013-01-30T22:30:04.123 に答える