在C ++中不使用括号类的原因是什么?

时间:2009-08-12 12:29:53

标签: c++ raii

通常需要完成以下任务:更改某些内容的状态,执行操作,然后将状态更改回原始状态。例如,在Win32 GDI中,需要更改背景颜色,然后进行一些绘制,然后再更改颜色。

可以直接完成:

COLORREF oldColor = SetBkColor( deviceContext, newColor );
drawStuff( deviceContext );
SetBkColor( deviceContext, oldColor );

或通过括号类来构造函数中的向前更改和析构函数中的向后更改:

CBkColorSwitcher switcher( deviceContext, newColor );
drawStuff( deviceContext );
//once control reaches end of block the switcher is destroyed and the change is reverted

括号类的优点是显而易见的 - 如果在更改之间抛出异常,则更改将被正确恢复。有什么缺点?

6 个答案:

答案 0 :(得分:12)

这实际上是一个众所周知且广泛使用的C ++习语,称为RAII。 Win32 API是C API,它们的实现模式不同。如果您使用C ++进行编程,最好使用RAII惯用法处理资源分配和释放,方法是在C API上编写精简包装器,或者更好地重用现有的,精心设计的C ++替换。 Java程序员可以将RAII视为 finally 子句的替代。

答案 1 :(得分:4)

一些缺点,你需要编写更多代码,最终创建更多对象。 你无法控制它的使用。使用它错误,你失去了好处。 e.g。

CBkColorSwitcher * switcher = new CBkColorSwitcher(......)

那就是说,我认为优点远大于缺点,而更喜欢括号类方法

答案 2 :(得分:2)

我认为这是一种最佳做法。我没有看到任何缺点(除了可读性之外?)

答案 3 :(得分:2)

我看到的缺点是(至少在你给出的例子中):

  • 除非代码的读者理解括号类的责任,否则不太清楚你实际在做什么。
  • 创建括号类的费用
  • 编写实现括号类的代码所需的时间比没有它的版本要长。

话虽如此,使用RAII是做到这一点的“正确”方法,其好处远大于缺点。

答案 4 :(得分:1)

一个缺点是你通常必须定义一个新的类,这往往会有点开销。

除此之外,它是(另一个)非常常见的RAII示例,并且通常是一种非常好的方法。

编辑:如果您没有编写类只有一个函数,那么可以使用shared_ptr在退出时执行一个代码块范围。我认为它对于大多数应用来说可能有点太可爱了。

答案 5 :(得分:1)

挑剔,但是:

  1. 代码大小,由于异常处理程序,您的代码会更大。
  2. 你需要编写很多类来处理所有类型的开关。
  3. 更大的堆栈。
  4. 始终在所有异常上执行代码,即使它不需要(例如,您只是希望应用程序崩溃)