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每次调用只会调用一次process,但由于这个特定系统的设计,我不能只newStateprocess. Stack Overflow 和其他地方的许多其他答案都说最好只返回对象,因为编译器无论如何都会移动它或 RVO 它,但这些都是在返回的对象是函数本地的情况下.

我不一定需要将状态对象放在 unique_ptr 后面,但这似乎是管理新状态对象的最简单方法。我的实际实现最后有一个指针直接转移到 unique_ptr 。

4

3 回答 3

1

It turns out that the original demo code is buggy- the unique_ptr never frees the pointer. The answer involves moving onto the local function space and then returning normally.

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在这种情况下,这不是一个最好的名字,它应该像fetchStateor 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_;
};

这将在构造处理器时默认构造 state_,但您可以使用optional包装器来防止这种情况。您仍然必须保证get_state仅在 after 调用process,这完全糟透了。

于 2013-01-30T22:30:04.123 回答