在 C++ 中不使用括号类的原因可能是什么?
通常需要完成以下任务:更改某物的状态,执行操作,然后将状态更改回原始状态。 例如,在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
一个缺点是您通常实际上必须定义一个新类,这往往会产生一些开销。
除此之外,它是(另一个)非常常见的 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.我看到的缺点是(至少在你给出的例子中):
话虽如此,使用 RAII 是做到这一点的“正确”方法,并且好处远远大于坏处。
The disadvantages I see are that (at least in the example you gave):
Having said this, using RAII is the "correct" way to do this and the benefits far outweigh the disadvantages.
我在这里吹毛求疵,但是:
I'm nitpicking here, but:
事实上,这是一个众所周知且广泛使用的 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.
有几个缺点,您需要编写更多代码,最终会创建更多对象。
您无法控制它的使用。 使用不当,您就会失去好处。 也就是说
,我认为优点远远超过缺点,并且更喜欢括号类方法
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.
That said, I think the advantages far outweigh the disadvantages and would prefer the bracket class approach
我认为这是一个最佳实践。 我没有看到任何缺点(除了可读性?)
I consider this a best practice. I don't see any disadvantages (except maybe readability?)