通过构造函数对C++对象进行部分重新初始化
Partial re-initialization of C++ object through constructor
我正在为C++对象的部分重新初始化寻找最佳模式。
对于部分重新初始化,我的意思是一些成员(代码示例中的step_param
)需要保留其值,而其他成员(代码实例中的value
)则需要重新初始化。
要点:应该避免与构造函数基本相同的init()或reset()成员函数的膨胀和冗余。
到目前为止,我有以下解决方案:
namespace reinit_example
{
struct reinit_t {} reinit;
struct stepper_t
{
int step_param; // keep parameter
int value;
stepper_t()
: step_param(1)
, value(step_param)
{}
stepper_t( const stepper_t & c, reinit_t )
: step_param(c.step_param)
, value(step_param)
{}
void step()
{
value += step_param;
}
};
void use_cases_1()
{
stepper_t c;
// use c
c.step();
// and later reinit
c = stepper_t(c,reinit);
}
} // namespace
它还应该与继承和组合配合良好:
namespace reinit_example
{
struct stepper_2_t : public stepper_t
{
int step_param_2; // keep parameter
int value_2;
public:
stepper_2_t()
: step_param_2(0)
, value_2(step_param_2)
{}
stepper_2_t( const stepper_2_t & cc, reinit_t )
: stepper_t(cc)
, step_param_2(cc.step_param_2)
, value_2(step_param+2)
{}
void step()
{
stepper_t::step();
value_2 += value + step_param_2;
}
};
struct stepper_comp_t
{
stepper_t c;
stepper_2_t cc;
public:
stepper_comp_t()
{}
stepper_comp_t( const stepper_comp_t & d, reinit_t )
: c(d.c,reinit)
, cc(d.cc,reinit)
{}
void step()
{
c.step();
cc.step();
}
};
void use_cases_2()
{
stepper_2_t cc;
// use cc, change config
cc.step();
// maybe change config
cc.step_param = 2;
// reinit
cc = stepper_2_t(cc,reinit);
stepper_comp_t d;
d = stepper_comp_t(d,reinit);
}
} // namespace
C++11非静态成员初始化使其更加简单:
#if __has_feature(cxx_nonstatic_member_init)
namespace reinit_example
{
struct stepper_11_t
{
int step_param = 0 ; // keep value
int value = step_param;
stepper_11_t()
{}
stepper_11_t( const stepper_11_t & c11, reinit_t )
: step_param(c11.step_param)
{}
};
void use_cases_3()
{
stepper_11_t c11;
c11 = stepper_11_t(c11,reinit);
}
} // namespace
#endif
用于测试:
int main()
{
reinit_example::use_cases_1();
reinit_example::use_cases_2();
#if __has_feature(cxx_nonstatic_member_init)
reinit_example::use_cases_3();
#endif
}
Jerry Coffin提出的解决方案:将参数移动到一个单独的结构中,并将其传递给构造函数以重新命名。
namespace reinit_example
{
struct stepper_config_t
{
struct config_t
{
config_t()
: step_param(1)
{}
int step_param;
int other_param;
};
config_t config;
int value;
stepper_config_t()
: value(config.step_param)
{}
stepper_config_t( const config_t & c)
: config(c)
, value(c.step_param)
{}
void step()
{
value += config.step_param;
}
};
void use_cases_4()
{
stepper_config_t c;
// use c
// and later reinit
c = stepper_config_t(c.config);
}
} // namespace
我认为您应该寻找完全不同的设计模式。
例如,"keeper"成员应该组成一个功能齐全的类,而您不想保留的其他成员将被视为该类的上下文(将是另一个类,用于对第一个类执行一些操作)。
这有点类似于轻量级的设计模式。
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- C++如何通过"constructor initialization"初始化行变量?
- 有没有办法使用初始化到第一行的指针访问 2d 数组的第二行?
- 不稳定的C :每行适应性变化多变量初始化
- 如何用行、列和值初始化 cv::Mat 数组?(在 c++ 类中)
- MPI - 当数组初始化值必须为常量时,如何为工作线程创建部分数组
- 无法使用SerialCommhelper在C 中打开/初始化串行端口
- Win API串行端口初始化后需要等待
- 如何从opencv cv::Mat或行主数组初始化特征矩阵
- 处理需要多行初始化'const'对象
- 使用指向2D数组行的指针来初始化其值.为什么会这样呢?
- 如何使参数构造函数初始化导致平方矩阵的行和列