gpt4 book ai didi

c++ - RAII状态管理

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:55:58 25 4
gpt4 key购买 nike

我需要改变一个状态。然后做事。然后将状态重置为原来的状态 - 例如:

auto oldActivationOrder = mdiArea->activationOrder();
mdiArea->setActivationOrder( QMdiArea::StackingOrder );
mdiArea->cascadeSubWindows();
mdiArea->setActivationOrder( oldActivationOrder );

我如何以 RAII 方式执行此操作?(C++ 11 和/或 14)

编辑:感谢您的所有回答。

有几个创建自定义类来处理状态更改的建议(BoBTFish、mindriot、Mattias Johansson)。这个解决方案看起来很好很清楚。但是,我认为将行数从 4 增加到 20+ 是一个缺点。如果经常使用,这会使代码膨胀。此外,似乎有些地方因为有一个单独的类(class)而丢失了。

Ami Tavory 建议使用 std::unique_ptr。这没有代码膨胀问题并保持局部性。但是,正如 Ami 还指出的那样,它可能不是最具可读性的解决方案。

sp2danny 提出了一个可以重复使用的通用状态更改类。这避免了代码膨胀,前提是它可以替换多个自定义类。我将接受这个答案 - 但我想正确的方法确实取决于上下文。

最佳答案

RAII:R资源A获取II初始化。

这也意味着资源释放就是破坏,尽管我从未见过人们谈论 RRID,尽管这是它更有用的一面。 (也许应该是终止,还是最终确定?)

重点是,您在对象的构造函数中做了一些工作,并在析构函数中有效地反转了它。这意味着无论您如何退出范围,都会执行清理:多个 return,多个 break,抛出异常,...(甚至 转到!)

class ScopedActivationOrderChange {
QMdiArea& area_; // the object to operate on
QMdiArea::WindowOrder oldOrder_; // save the old state

public:
ScopedActivationOrderChange(QMdiArea& area, ActivationOrder newOrder)
: area_(area)
, oldOrder_(area_.activationOrder()) // save old state
{
area_.setActivationOrder(newOrder); // set new state
}

~ScopedActivationOrderChange()
{
area_.setActivationOrder(oldOrder_); // reset to old state
}
};

// ...

{ // <-- new scope, just to establish lifetime of the change
ScopedActivationOrderChange orderChange{*mdiArea, QMdiArea::StackingOrder};
mdiArea->cascadeSubWindows();
} // <-- end of scope, change is reversed

标准库不为此提供任何通用工具。它确实提供了一些用于更具体的用途,例如 std::unique_ptr用于删除动态分配的对象,在某些情况下可以用于其他事情,尽管它有点难看。 std::vector可以看作是动态数组的 RAII 类,还提供一些其他管理工具,但是这个类不太容易被滥用于其他目的。

关于c++ - RAII状态管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35911317/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com