RAII = リソース取得は初期化です
Ref Counting = "貧乏人の GC"
一緒にすると、それらは非常に強力です (デストラクタが呼び出されたときに解放をスローする、VBO を保持する参照カウントされた 3D オブジェクトのように)。
さて、質問は -- RAII は C++ 以外のどの言語にも存在しますか? 特に、ポインター演算/バッファー オーバーフローを許可しない言語はありますか?
RAII = リソース取得は初期化です
Ref Counting = "貧乏人の GC"
一緒にすると、それらは非常に強力です (デストラクタが呼び出されたときに解放をスローする、VBO を保持する参照カウントされた 3D オブジェクトのように)。
さて、質問は -- RAII は C++ 以外のどの言語にも存在しますか? 特に、ポインター演算/バッファー オーバーフローを許可しない言語はありますか?
厳密には RAII ではありませんが、Python にはwith ステートメントがあり、C# にはusing ステートメントがあります。
DにはRAIIがありますが、まだポインター演算があります:(しかし、実際に使用する必要はありません。
perl、python(C)、php、およびtclは参照カウントされ、参照カウントがゼロになるとオブジェクトを破棄するメカニズムがあります。これは、変数がスコープ外になるとすぐに発生する可能性があります。ビルトインタイプは自動的にリリースされます。ユーザー定義クラスには、リリース時に呼び出されるデストラクタを定義する方法があります。
いくつかのエッジケースがあります。グローバル変数は最後まで解放されず、循環参照は最後まで解放されない可能性があります(ただし、phpは最近このケースを処理するgcを実装し、python 2は循環検出器を追加しました)。
Python(Jython、Unladen Swallow、IronPythonなどのバリアントではなく標準のCPython)は、オブジェクトの参照カウントを使用します。
これに伴い、RAIIと(ほとんど)決定論的なガベージコレクションもあります。たとえば、これは決定論的にファイルを閉じるときに機能するはずです。
def a():
fp = open('/my/file', 'r')
return fp.read()
メモfp.close()
が呼び出されることはありません。fp
スコープから外れるとすぐに、オブジェクトは破棄されます。ただし、次のように、決定論的なファイナライズが保証されない場合があります。
sys.last_traceback
最後のトレースバックを保持することに注意してください)したがって、Pythonには理論的には決定論的なファイナライズがありますが、例外(IOErrorなど)によってオブジェクトがライブのままになる可能性がある場合は、リソースを明示的に閉じることをお勧めします。
Perl 5 には、すべての参照がスコープ外になったときに呼び出されることが保証されている参照カウントとデストラクタがあるため、この言語では RAII を使用できますが、ほとんどの Perl プログラマーはこの用語を使用しません。
また、Perl 5 は生のポインタを Perl コードに公開しません。
しかし、Perl 6 には実際のガベージ コレクタがあり、実際にはガベージ コレクタを切り替えることができます。そのため、特定の順序で収集されることに依存することはできません。
Python と Lua は参照カウントを使用していると思います。
Valaのオブジェクトのメモリ管理は参照カウントに基づいており、RAII を備えています (デストラクタが決定論的に呼び出されるという意味で)。典型的な使用例は、refcounting によるオーバーヘッドがほとんどない GUI を作成することです。たとえば、相互運用性のため、または追加のパフォーマンスが必要な場合は、ポインターを使用して参照カウントをバイパスできますが、ほとんどの場合、ポインターがなくても問題ありません。また、参照をowned
orとしてマークしてunowned
所有権を譲渡することもでき、多くの場合、参照カウントを省略できます (たとえば、オブジェクトが関数をエスケープしない場合)。Vala は GObject/GTK と密接に関連しているため、そのエコシステムで作業したい場合にのみ使用する意味があります。
もう 1 つの興味深い候補はRustです。ポインターとガベージ コレクションもありますが、どちらもオプションです。C++ のスマート ポインターと同等のものを使用して完全にプログラムを作成でき、リークがないことが保証され、RAII をサポートします。また、Vala のような参照所有権の概念もありますが、もう少し複雑です。基本的に、Rust を使用すると、メモリの管理方法を完全に制御できます。ベア メタル レベルで作業することができ、その中にカーネルを書き込むこともできます。または、GC を使用して高レベルで作業することも、その間のあらゆる作業を行うこともできます。ほとんどの場合、メモリやその他のポインターのリークから保護されます。関連するバグ。欠点は、かなり複雑なことです。まだ開発中であるため、変更される可能性があります。