我要用相当复杂的设置过程构建一个时间跨度类。将有几个构造函数。在构造函数中调用setter是不是一个坏主意?
我知道如果在派生类中覆盖setter,我不应该直接调用非私有的setter来避免问题。我想要创建真正的setter private并包装公共setter并在构造函数中调用私有setter以避免必须将其声明为final。
class A {
public:
A(sometype data1, sometype data2);
void setData1(sometype data1);
void setData2(sometype data2);
private:
void p_setData1(sometype data1);
void p_setData2(sometype data2);
};
A::A(sometype data1, sometype data2) {
p_setData1(data1);
p_setData2(data2);
}
void A::setData1(sometype data1) { p_setData1(data1); }
void A::setData2(sometype data2) { p_setData2(data2); }
void A::p_setData1(sometype data1) {
//Complex validation and calculations
}
void A::p_setData2(sometype data2) {
//Complex validation and calculations
}
有没有人有最佳做法?
答案 0 :(得分:6)
关于
“我知道如果在派生类中覆盖setter,我不应该直接调用非私有的setter来避免问题。”
这在很大程度上不是问题。即使使用虚拟设置器,构建类A
时使用的定义也是动态类型A
的定义。 C ++是安全的,而不是Java和C#(在你建立基类不变量之前,你冒着虚拟调用最终导致类代码的风险,并且爆炸)。
关于最佳实践,它应该对制定者和吸气者持批评态度。它们确实具有内省语言的目的,例如, “设计师”工具可以使用它们,但在C ++中却没有那么多。所以,最好的做法是总是问,我是否真的需要它们,我可以设计一些其他方式(例如move
而不是setxy
(可能听起来不太相似,但考虑来自构造函数的调用 - move
在施工期间没那么有意义))。
答案 1 :(得分:3)
在构造函数中调用setter是不是一个坏主意?
否 - 在构造函数中使用setter允许您重用setter逻辑,而无需在setter方法和构造函数中定义它。这意味着您只需要在一个地方而不是在setter和构造函数中进行更改。