从非本地返回右值引用



>我有一个查询内部状态对象的类:

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,但由于这个特定系统的设计,我不能只从process返回newState。Stack Overflow 和其他地方的许多其他答案都说,最好只返回对象,因为编译器会移动它或 RVO 它,如果可以的话,但这些都是在返回的对象是函数本地的情况下。

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

事实证明,原始演示代码有问题 - 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;
    }
};

只返回状态有什么问题

struct state {};
class processor {
public:
  void process() {
    state_ = State();
  }
  state get_state() {
    return std::move(state_);
  }
private:
  state state_;
};

这将默认构造state_在构造处理器时,但您可以使用optional包装器来防止这种情况。你仍然需要保证 get_state 仅在 process 之后调用,这彻头彻尾的糟透了。

您可以返回类型为 std::unique_ptr<State>state,它将与 std::move(state) 完美移动。在这种情况下,当按值返回整个state对象时,您无需复制该对象。如果调用方未捕获state对象,则会自动销毁该对象。对于复杂的堆分配对象,这是非常有效的方法。但要小心,通过移动state清除Processor对象的状态。因此,在这种情况下,getState不是最好的名称,它应该像 fetchStatepopState .

相关内容

  • 没有找到相关文章

最新更新