Programming in D by Ali Çehreli
Author:Ali Çehreli [Çehreli, Ali]
Language: eng
Format: epub, pdf
Tags: d, D programming language, dlang, tutorial
Publisher: Ali Çehreli
Published: 0101-01-01T00: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
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.
Coding Theory | Localization |
Logic | Object-Oriented Design |
Performance Optimization | Quality Control |
Reengineering | Robohelp |
Software Development | Software Reuse |
Structured Design | Testing |
Tools | UML |
Deep Learning with Python by François Chollet(11976)
Hello! Python by Anthony Briggs(9424)
OCA Java SE 8 Programmer I Certification Guide by Mala Gupta(9391)
The Mikado Method by Ola Ellnestam Daniel Brolund(9353)
Dependency Injection in .NET by Mark Seemann(8898)
Algorithms of the Intelligent Web by Haralambos Marmanis;Dmitry Babenko(7896)
Test-Driven iOS Development with Swift 4 by Dominik Hauser(7416)
Grails in Action by Glen Smith Peter Ledbrook(7333)
The Well-Grounded Java Developer by Benjamin J. Evans Martijn Verburg(7162)
Secrets of the JavaScript Ninja by John Resig Bear Bibeault(6006)
Kotlin in Action by Dmitry Jemerov(4684)
Practical Vim (for Kathryn Amaral) by Drew Neil(3748)
Cracking the GRE Premium Edition with 6 Practice Tests, 2015 (Graduate School Test Preparation) by Princeton Review(3625)
Linux Device Driver Development Cookbook by Rodolfo Giometti(3533)
Learn Windows PowerShell in a Month of Lunches by Don Jones(3279)
Becoming a Dynamics 365 Finance and Supply Chain Solution Architect by Brent Dawson(3191)
Microservices with Go by Alexander Shuiskov(2977)
Practical Design Patterns for Java Developers by Miroslav Wengner(2895)
Learning Java by Patrick Niemeyer & Daniel Leuck(2891)