在C++的fluent接口中设置后立即调用析构函数



我只想创建一个类来设置函数的参数。我正在使用一个流畅的界面。某些函数将对象返回到设置参数,实际代码将在该对象的析构函数中执行。

首先,这是个好主意吗?当我有很多参数时,这是提高代码可读性的常用方法吗?或者我应该用另一种方法来做?我很乐意就此提供建议。

如果可以的话,如何防止意外地将对象保存到局部变量?在这种情况下,析构函数将在变量作用域的末尾调用。

示例:

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++中,由于RAII的原因,您不需要finally

我认为你不能阻止终身扩展/局部变量。我们没有属性[[discard]],只有属性[[nodiscard]]

但是你为什么不在SetA((中做这项工作呢?对我来说会更清楚吗?

一个很好的理由是,如果你需要所有的参数数据来完成这项工作。。。

更新

有一种选择。您可以使您的对象不可复制/移动:

MyClass() = default;
MyClass(const MyClass&) = delete;
MyClass(MyClass&&) = delete;

但用这样的方法,你不可能有"SomeFunction"这样的东西。当然,这样的工厂函数可能会导致一个副本,该副本也会调用析构函数。


作为一个建议,我只需要明确地做:

SomeFunction()
.SetA()
.SetB()
.Exec()
;

最新更新