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

发布于 2024-08-01 20:07:59 字数 565 浏览 6 评论 0原文

通常需要完成以下任务:更改某物的状态,执行操作,然后将状态更改回原始状态。 例如,在 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

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

It's often needed to accomplish the following task: change the state of something, do action, then change the state back to original. For example, in Win32 GDI it's needed to change background color, then do some drawing, then change the color back.

It can be either done directly:

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

or via a bracket class that would do the forward change in the constructor and the backward change in the destructor:

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

The advantage of a bracket class is obvious - if an exception is thrown in between the changes the change is reverted correctly. What are the disadvantages?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

三生池水覆流年 2024-08-08 20:08:00

一个缺点是您通常实际上必须定义一个新类,这往往会产生一些开销。

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

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

One disadvantage is that you usually actually have to define a new class which tends to be a bit of an overhead.

That aside it's (another) very common RAII example and is, in general, a very good approach.

Edit: If, instead of writing a class you just have a function, you can use shared_ptr to execute an arbritary code block on exit from a scope. I think it's probably a bit too cute for most applications though.

画尸师 2024-08-08 20:08:00

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

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

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

The disadvantages I see are that (at least in the example you gave):

  • It is less clear as to what you are actually doing unless the reader of the code understands the responsibility of the bracket class.
  • The cost of creating the bracket class
  • Writing the code to implement the bracket class will take longer than a version without it.

Having said this, using RAII is the "correct" way to do this and the benefits far outweigh the disadvantages.

总攻大人 2024-08-08 20:08:00

我在这里吹毛求疵,但是:

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

I'm nitpicking here, but:

  1. Code size, your code will be bigger because of the exception handler.
  2. You need to write a lot of class to handle all sort of switches.
  3. Bigger stack.
  4. Always preforming code on all exceptions, even if its not need (for example you just want the application to crash)
放血 2024-08-08 20:07:59

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

This is in fact a well known and widely used C++ idiom known as RAII. Win32 APIs are C APIs and their implementation patterns are different. If you are programming in C++, it is better to handle resource allocation and deallocation using the RAII idiom, by writing thin wrappers on the C API or better re-use existing, well-designed C++ replacements. Java programmers can look upon RAII as a replacement for the finally clause.

眼眸 2024-08-08 20:07:59

有几个缺点,您需要编写更多代码,最终会创建更多对象。
您无法控制它的使用。 使用不当,您就会失去好处。 也就是说

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

,我认为优点远远超过缺点,并且更喜欢括号类方法

A couple of disadvantages, you need to write more code, you end up creating more objects.
You have no control over the use of it. Use it wrong and you lose the benefits. e.g.

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

That said, I think the advantages far outweigh the disadvantages and would prefer the bracket class approach

笑饮青盏花 2024-08-08 20:07:59

我认为这是一个最佳实践。 我没有看到任何缺点(除了可读性?)

I consider this a best practice. I don't see any disadvantages (except maybe readability?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文