将对象重置为初始状态的模式

Patterns for resetting objects to initial state

假设我有一个对象,其成员的构造成本很高,并且需要 reset() 函数将其重置为初始状态:

struct Example
{
    // option 1: efficient, but need to duplicate initialization logic of reset() 
    Example(int param) : expensive_member_(param), param_(param)
    {
    }
    /* option 2: less code, but initializes expensive_member_ twice
    Example(int param) : param_(param)
    { 
        reset();
    }*/

    void reset()
    {
         expensive_member_ = ClassWithExpensiveConstructor(param_);
    }

    ClassWithExpensiveConstructor expensive_member_;
    int param_;
}

是否有更好的方法 of/pattern 可以有效地将对象重置为初始状态,而无需复制初始化列表和 reset 函数中的初始化逻辑?

编辑:如果没有通用的方法来实现我想要的,那也是这个问题可以接受的结果!

如果ClassWithExpensiveConstructor是那个class,construction/reset是昂贵的,应该是它优化了操作。

另一种选择是在 const 成员中保留初始值的副本,假设副本 construction/assignment 并不昂贵。这将使用更多内存,但如果您碰巧经常调用 Example::reset() 会提高性能。

struct Example
{
    Example(int param)
    : expensive_member_backup_(param)
    , expensive_member_(expensive_mamber_backup)
    , param_(param)
    {
    }

    void reset()
    {
         expensive_member_ = expensive_member_backup_;
    }

    const ClassWithExpensiveConstructor expensive_member_backup_;
    ClassWithExpensiveConstructor expensive_member_;
    int param_;
}

你可以让你的 ExpensiveMember 成为一个指针,在这种情况下你的选项 2 将不会在 Example 构造函数中调用 ExpensiveMember 构造函数,除非你明确地调用它:

struct Example
{
    Example(int param) : expensive_member_(), param_(param)
    { 
         reset();
    }

    ~Example() {
         delete expensive_member_;   // better use unique_ptr etc
    }

    // Also a copy constructor and assignment operator 
    // are needed to avoid memory problems such as double-delete.
    // Also, better use unique_ptr etc.
    // This answer does not use unique_ptr just to make the main idea more clear.

    void reset()
    {
         delete expensive_member_;   // better use unique_ptr etc
         expensive_member_ = new ClassWithExpensiveConstructor(param_);
    }

    ClassWithExpensiveConstructor* expensive_member_;  // better use unique_ptr etc
    int param_;
}

一个简单的解决方案是使用(智能或常规)指针,以便初始化成员(即指针)的成本变小,并且实际对象仅在对 [=11 的调用中初始化=]:

 struct Example
 {
    Example(int param) : param_(param)
    { 
        reset();
    }

    void reset()
    {
         p.reset(new ClassWithExpensiveConstructor(param_));
    }

    unique_ptr<ClassWithExpensiveConstructor> p;
    int param_;
}