Programming in D: Tutorial and Reference by Ali Cehreli
Author:Ali Cehreli [Cehreli, Ali]
Language: eng
Format: azw3, pdf
Tags: D programming language, d, tutorial, dlang
Publisher: Ali Cehreli
Published: 2015-12-11T16:00:00+00:00
scoped() to call the destructor automatically
The program above has a weakness: The scopes may be exited before the destroy() lines are executed, commonly by thrown exceptions. If the destroy() lines must be executed even when exceptions are thrown, a solution is to take advantage of scope() and other features that we have seen in the Exceptions chapter.
Another solution is to construct class objects by std.typecons.scoped instead of by the new keyword. scoped() wraps the class object inside a struct and the destructor of that struct object destroys the class object when itself goes out of scope.
The effect of scoped() is to make class objects behave similar to struct objects regarding lifetimes.
With the following changes, the program produces the expected output as before:
import std.typecons; // ... void main() { const courses = scoped!XmlElement("courses", 0); foreach (courseId; 0 .. 2) { const courseTag = "course" ~ to!string(courseId); const courseElement = scoped!XmlElement(courseTag, 1); foreach (i; 0 .. 3) { const gradeElement = scoped!XmlElement("grade", 2); const randomGrade = uniform(50, 101); writeln(indentationString(3), randomGrade); } } }
Note that there are no destroy() lines anymore.
scoped() is a function that returns a special struct object encapsulating the actual class object. The returned object acts as a proxy to the encapsulated one. (In fact, the type of courses above is Scoped, not XmlElement.)
When the destructor of the struct object is called automatically as its lifetime ends, it calls destroy() on the class object that it encapsulates. (This is an application of the Resource Acquisition Is Initialization (RAII) idiom. scoped() achieves this by the help of templates and alias this, both of which we will see in later chapters.)
It is desirable for a proxy object to be used as conveniently as possible. In fact, the object that scoped() returns can be used exactly like the actual class type. For example, the member functions of the actual type can be called on it:
import std.typecons; class C { void foo() { } } void main() { auto p = scoped!C(); p.foo(); // Proxy object p is being used as type C }
However, that convenience comes with a price: The proxy object may hand out a reference to the actual object right before destroying it. This can happen when the actual class type is specified explicitly on the left hand-side:
C c = scoped!C(); // ← BUG c.foo(); // ← Accesses a destroyed object
In that definition, c is not the proxy object; rather, as defined by the programmer, a class variable referencing the encapsulated object. Unfortunately, the proxy object that is constructed on the right-hand side gets terminated at the end of the expression that constructs it. As a result, using c in the program would be an error, likely causing a runtime error:
Segmentation fault
For that reason, do not define scoped() variables by the actual type:
C a = scoped!C(); // ← BUG auto b = scoped!C(); // ← correct const c = scoped!C(); // ← correct immutable d = scoped!C(); // ← correct
Download
Programming in D: Tutorial and Reference by Ali Cehreli.pdf
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.
API Testing and Development with Postman by Dave Westerveld(3619)
Learning C# by Developing Games with Unity 2020 by Harrison Ferrone(2615)
Software Architecture for Busy Developers by Stéphane Eyskens(2322)
2021 Beginners Guide to Python Programming Language: A Crash Course to Mastering Python in One Hour by Elmer Gary & Elmer Gary(1884)
Machine Learning for Algorithmic Trading by Stefan Jansen(1629)
Hands-On ROS for Robotics Programming by Bernardo Ronquillo Japón(1572)
Delphi GUI Programming with FireMonkey by Andrea Magni(1457)
Game Development Projects with Unreal Engine by Hammad Fozi & Goncalo Marques & David Pereira & Devin Sherry(1402)
Cloud Native with Kubernetes by Alexander Raul(1374)
Datadog Cloud Monitoring Quick Start Guide by Thomas Kurian Theakanath(1346)
Software Architecture Patterns for Serverless Systems by John Gilbert(1338)
Practical Node-RED Programming by Taiji Hagino(1336)
Automate It with Zapier by Kelly Goss(1318)
Practical System Programming for Rust Developers by Prabhu Eshwarla(1312)
Delphi Programming Projects by William Duarte(1296)
Mastering React Test-Driven Development by Daniel Irvine(1290)
Developing Multi-Platform Apps with Visual Studio Code by Ovais Mehboob Ahmed Khan & Khusro Habib & Chris Dias(1253)
Ghidra Software Reverse Engineering for Beginners by A. P. David(1244)
Learn Spring for Android Application Development by S. M. Mohi Us Sunnat(1235)
