将对象重置为初始状态的模式
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_;
}
假设我有一个对象,其成员的构造成本很高,并且需要 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_;
}