C++流畅接口设置后立即调用析构函数
Immediately calling destructor after setting in the fluent interface in C++
我想创建一个 class 仅用于设置函数的参数。
我为此使用了流畅的界面。
一些函数returns设置参数的对象和真正的代码将在这个对象的析构函数中执行。
首先,这是个好主意吗?当我有很多参数时,这是提高代码可读性的常用方法吗?或者我应该用另一种方法来做到这一点?我很乐意就此提出建议。
如果没问题,如何防止不小心将对象保存到局部变量?在这种情况下,析构函数将在变量范围的末尾被调用。
示例:
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;
}
一般来说,如果你想强制发生某些事情,即使发生异常,析构函数也是一个好地方(但请注意,destructros 默认声明为 noexcept(true)
)。
我个人将它用于“finally”块(noexcept(false)
)。但通常在 C++ 中你不需要 finally
因为 RAII.
我认为你无法阻止生命周期延长/局部变量。而我们没有属性[[discard]]
,只有[[nodiscard]]
.
但是为什么你不在 SetA() 中做这些工作呢?对我来说会更清楚吗?
一个很好的理由是,如果您需要所有参数数据来完成工作...
更新
只有一种选择。您可以使您的对象不可复制/不可移动:
MyClass() = default;
MyClass(const MyClass&) = delete;
MyClass(MyClass&&) = delete;
但是用这种方法你不可能有像 'SomeFunction' 这样的东西。当然,这样的工厂函数也可能会导致调用析构函数的副本。
作为一个建议,我会简单地做到这一点:
SomeFunction()
.SetA()
.SetB()
.Exec()
;
我想创建一个 class 仅用于设置函数的参数。 我为此使用了流畅的界面。 一些函数returns设置参数的对象和真正的代码将在这个对象的析构函数中执行。
首先,这是个好主意吗?当我有很多参数时,这是提高代码可读性的常用方法吗?或者我应该用另一种方法来做到这一点?我很乐意就此提出建议。
如果没问题,如何防止不小心将对象保存到局部变量?在这种情况下,析构函数将在变量范围的末尾被调用。
示例:
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;
}
一般来说,如果你想强制发生某些事情,即使发生异常,析构函数也是一个好地方(但请注意,destructros 默认声明为 noexcept(true)
)。
我个人将它用于“finally”块(noexcept(false)
)。但通常在 C++ 中你不需要 finally
因为 RAII.
我认为你无法阻止生命周期延长/局部变量。而我们没有属性[[discard]]
,只有[[nodiscard]]
.
但是为什么你不在 SetA() 中做这些工作呢?对我来说会更清楚吗?
一个很好的理由是,如果您需要所有参数数据来完成工作...
更新
只有一种选择。您可以使您的对象不可复制/不可移动:
MyClass() = default;
MyClass(const MyClass&) = delete;
MyClass(MyClass&&) = delete;
但是用这种方法你不可能有像 'SomeFunction' 这样的东西。当然,这样的工厂函数也可能会导致调用析构函数的副本。
作为一个建议,我会简单地做到这一点:
SomeFunction()
.SetA()
.SetB()
.Exec()
;