我想创建一个仅用于设置功能参数的类。我为此使用了流畅的界面。一些函数将对象返回到设置参数,并且实际代码将在该对象的析构函数中执行。
首先,这是个好主意吗?当我有很多参数时,这是提高代码可读性的常用方法吗?或者,也许我应该使用另一种方式来做到这一点?我很乐意就此提出建议。
如果可以,如何防止意外将对象保存到局部变量?在这种情况下,析构函数将在变量作用域的末尾被调用。
例:
class MyClass {
public:
~MyClass() noexcept {
// some code to execute immediately after setting params A and B
}
// abstract setting methods
MyClass &SetA() { return *this; }
MyClass &SetB() { return *this; }
};
MyClass SomeFunction() {
return MyClass();
}
int main() {
// Correct usage:
SomeFunction()
.SetA()
.SetB();
// destructor here
// I want to prevent it:
auto my_class = SomeFunction();
my_class
.SetA()
.SetB();
{
auto my_class2 = SomeFunction();
my_class2
.SetA()
.SetB();
// destructor of `my_class2` here
}
// destructor of `my_class` here.
return 0;
}
通常,如果您要强制即使发生异常也要发生某些事情,则析构函数是个好地方(但请注意,noexcept(true)
默认情况下声明了析构函数)。
我个人将其用于“最终”代码块(带有noexcept(false)
)。但是通常在C ++中,finally
由于RAII,您不需要。
我认为您无法避免生命周期扩展/局部变量。而且我们没有属性[[discard]]
,只有[[nodiscard]]
。
但是,为什么不在SetA()中进行这项工作呢?对我来说会更清楚吗?
一个很好的理由是,如果您需要所有参数数据来完成工作……
有一种选择。您可以使对象不可复制/不可移动:
MyClass() = default;
MyClass(const MyClass&) = delete;
MyClass(MyClass&&) = delete;
但是使用这种方法,您将无法获得“ SomeFunction”之类的东西。当然,这样的工厂函数可能会导致一个副本,该副本也调用您的析构函数。
作为建议,我只需要明确地做一下:
SomeFunction()
.SetA()
.SetB()
.Exec()
;
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句