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

时间:2015-07-27 09:08:27

标签: c++ c++11 initialization member-initialization

假设我有一个构造成本昂贵的对象,并且需要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_;
}

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

编辑:如果没有达到我想要的通用方式,这也是这个问题的可接受结果!

3 个答案:

答案 0 :(得分:1)

如果ClassWithExpensiveConstructor是构造/重置费用昂贵的一个类,那么优化操作应该是它。

另一种选择是在const成员中保留初始值的副本,假设复制构造/分配并不昂贵。这会占用更多内存,但如果碰巧大量调用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_;
}

答案 1 :(得分:1)

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

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_;
}

答案 2 :(得分:1)

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

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

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

    unique_ptr<ClassWithExpensiveConstructor> p;
    int param_;
}