Do programmers of other languages, besides C++, us

2019-02-02 03:01发布

I've noticed RAII has been getting lots of attention on Stackoverflow, but in my circles (mostly C++) RAII is so obvious its like asking what's a class or a destructor.

So I'm really curious if that's because I'm surrounded daily, by hard-core C++ programmers, and RAII just isn't that well known in general (including C++), or if all this questioning on Stackoverflow is due to the fact that I'm now in contact with programmers that didn't grow up with C++, and in other languages people just don't use/know about RAII?

17条回答
Viruses.
2楼-- · 2019-02-02 03:09

I use C++˚ RAII all the time but I've also developed in VB6 for a long time and RAII has always been a widely-used concept there (although I've never heard anyone call it that).

In fact, many VB6 programs rely on RAII quite heavily. One of the more curious uses that I've repeatedly seen is the following small class:

' WaitCursor.cls '
Private m_OldCursor As MousePointerConstants

Public Sub Class_Inititialize()
    m_OldCursor = Screen.MousePointer
    Screen.MousePointer = vbHourGlass
End Sub

Public Sub Class_Terminate()
    Screen.MousePointer = m_OldCursor
End Sub

Usage:

Public Sub MyButton_Click()
    Dim WC As New WaitCursor

    ' … Time-consuming operation. '
End Sub

Once the time-consuming operation terminates, the original cursor gets restored automatically.

查看更多
成全新的幸福
3楼-- · 2019-02-02 03:10

First of all I'm very surprised it's not more well known! I totally thought RAII was, at least, obvious to C++ programmers. However now I guess I can understand why people actually ask about it. I'm surrounded, and my self must be, C++ freaks...

So my secret.. I guess that would be, that I used to read Meyers, Sutter [EDIT:] and Andrei all the time years ago until I just grokked it.

查看更多
戒情不戒烟
4楼-- · 2019-02-02 03:10

RAII is a way in C++ to make sure a cleanup procedure is executed after a block of code regardless of what happens in the code: the code executes till the end properly or raises an exception. An already cited example is automatically closing a file after its processing, see answer here.

In other languages you use other mechanism to achieve that.

In Java you have try { } finally {} constructs:

try {
  BufferedReader file = new BufferedReader(new FileReader("infilename"));
  // do something with file
}
finally {
    file.close();
}

In Ruby you have the automatic block argument:

File.open("foo.txt") do | file |
  # do something with file
end

In Lisp you have unwind-protect and the predefined with-XXX

(with-open-file (file "foo.txt")
  ;; do something with file
)

In Scheme you have dynamic-wind and the predefined with-XXXXX:

(with-input-from-file "foo.txt"
  (lambda ()
    ;; do something 
)

in Python you have try finally

try
  file = open("foo.txt")
  # do something with file
finally:
  file.close()

The C++ solution as RAII is rather clumsy in that it forces you to create one class for all kinds of cleanup you have to do. This may forces you to write a lot of small silly classes.

Other examples of RAII are:

  • unlocking a mutex after acquisition
  • closing a database connection after opening
  • freeing memory after allocation
  • logging on entry and exit of a block of code
  • ...
查看更多
The star\"
5楼-- · 2019-02-02 03:11

The thing with RAII is that it requires deterministic finalization something that is guaranteed for stackbased objects in C++. Languages like C# and Java that relies on garbage collection doesn't have this guarantee so it has to be "bolted" on somehow. In C# this is done by implementing IDisposable and much of the same usage patterns then crops up basicly that's one of the motivators for the "using" statement, it ensures Disposal and is very well known and used.

So basicly the idiom is there, it just doesn't have a fancy name.

查看更多
\"骚年 ilove
6楼-- · 2019-02-02 03:13

The problem with RAII is the acronym. It has no obvious correlation to the concept. What does this have to do with stack allocation? That is what it comes down to. C++ gives you the ability to allocate objects on the stack and guarantee that their destructors are called when the stack is unwound. In light of that, does RAII sound like a meaningful way of encapsulating that? No. I never heard of RAII until I came here a few weeks ago, and I even had to laugh hard when I read someone had posted that they would never hire a C++ programmer who'd didn't know what RAII was. Surely the concept is well known to most all competent professional C++ developers. It's just that the acronym is poorly conceived.

查看更多
对你真心纯属浪费
7楼-- · 2019-02-02 03:13

A modification of @Pierre's answer:

In Python:

with open("foo.txt", "w") as f:
    f.write("abc")

f.close() is called automatically whether an exception were raised or not.

In general it can be done using contextlib.closing, from the documenation:

closing(thing): return a context manager that closes thing upon completion of the block. This is basically equivalent to:

from contextlib import contextmanager

@contextmanager
def closing(thing):
    try:
        yield thing
    finally:
        thing.close()

And lets you write code like this:

from __future__ import with_statement # required for python version < 2.6
from contextlib import closing
import urllib

with closing(urllib.urlopen('http://www.python.org')) as page:
    for line in page:
        print line

without needing to explicitly close page. Even if an error occurs, page.close() will be called when the with block is exited.

查看更多
登录 后发表回答