Skip to content

Commit 39387eb

Browse files
authored
Merge pull request #4826 from Rageking8/small-nits-for-destructors-cpp
Small nits for destructors cpp
2 parents 6d659ef + db1c552 commit 39387eb

File tree

1 file changed

+16
-33
lines changed

1 file changed

+16
-33
lines changed

docs/cpp/destructors-cpp.md

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
22
description: "Learn more about: Destructors (C++)"
33
title: "Destructors (C++)"
4-
ms.date: "07/20/2019"
4+
ms.date: "11/29/2023"
55
helpviewer_keywords: ["objects [C++], destroying", "destructors, C++"]
66
---
77
# Destructors (C++)
88

9-
A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to **`delete`**. A destructor has the same name as the class, preceded by a tilde (`~`). For example, the destructor for class `String` is declared: `~String()`.
9+
A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to **`delete`** or **`delete[]`**. A destructor has the same name as the class and is preceded by a tilde (`~`). For example, the destructor for class `String` is declared: `~String()`.
1010

11-
If you don't define a destructor, the compiler provides a default one; for many classes this is sufficient. You only need to define a custom destructor when the class stores handles to system resources that need to be released, or pointers that own the memory they point to.
11+
If you don't define a destructor, the compiler provides a default one, and for some classes this is sufficient. You need to define a custom destructor when the class maintains resources that must be explicitly released, such as handles to system resources or pointers to memory that should be released when an instance of the class is destroyed.
1212

1313
Consider the following declaration of a `String` class:
1414

@@ -49,7 +49,7 @@ int main() {
4949
}
5050
```
5151
52-
In the preceding example, the destructor `String::~String` uses the **`delete`** operator to deallocate the space dynamically allocated for text storage.
52+
In the preceding example, the destructor `String::~String` uses the **`delete[]`** operator to deallocate the space dynamically allocated for text storage.
5353
5454
## Declaring destructors
5555
@@ -58,25 +58,19 @@ Destructors are functions with the same name as the class but preceded by a tild
5858
Several rules govern the declaration of destructors. Destructors:
5959
6060
- Don't accept arguments.
61-
6261
- Don't return a value (or **`void`**).
63-
6462
- Can't be declared as **`const`**, **`volatile`**, or **`static`**. However, they can be invoked for the destruction of objects declared as **`const`**, **`volatile`**, or **`static`**.
65-
6663
- Can be declared as **`virtual`**. Using virtual destructors, you can destroy objects without knowing their type—the correct destructor for the object is invoked using the virtual function mechanism. Destructors can also be declared as pure virtual functions for abstract classes.
6764
6865
## Using destructors
6966
7067
Destructors are called when one of the following events occurs:
7168
7269
- A local (automatic) object with block scope goes out of scope.
73-
74-
- An object allocated using the **`new`** operator is explicitly deallocated using **`delete`**.
75-
70+
- Use **`delete`** to deallocate an object allocated using **`new`**. Using **`delete[]`** results in undefined behaviour.
71+
- Use **`delete[]`** to deallocate an object allocated using **`new[]`**. Using **`delete`** results in undefined behaviour.
7672
- The lifetime of a temporary object ends.
77-
7873
- A program ends and global or static objects exist.
79-
8074
- The destructor is explicitly called using the destructor function's fully qualified name.
8175
8276
Destructors can freely call class member functions and access class member data.
@@ -123,8 +117,10 @@ int main() {
123117
B3 * b2 = new B3;
124118
delete b2;
125119
}
120+
```
126121

127-
Output: A3 dtor
122+
```output
123+
A3 dtor
128124
A2 dtor
129125
A1 dtor
130126
@@ -143,48 +139,35 @@ Destructors for virtual base classes are called in the reverse order of their ap
143139
Five classes, labeled A through E, are arranged in an inheritance graph. Class E is the base class of B, C, and D. Classes C and D are the base class of A and B.
144140
:::image-end:::
145141

146-
The following lists the class heads for the classes shown in the figure.
142+
The following lists the class definitions for the classes shown in the figure:
147143

148144
```cpp
149-
class A
150-
class B
151-
class C : virtual public A, virtual public B
152-
class D : virtual public A, virtual public B
153-
class E : public C, public D, virtual public B
145+
class A {};
146+
class B {};
147+
class C : virtual public A, virtual public B {};
148+
class D : virtual public A, virtual public B {};
149+
class E : public C, public D, virtual public B {};
154150
```
155151
156152
To determine the order of destruction of the virtual base classes of an object of type `E`, the compiler builds a list by applying the following algorithm:
157153
158154
1. Traverse the graph left, starting at the deepest point in the graph (in this case, `E`).
159-
160155
1. Perform leftward traversals until all nodes have been visited. Note the name of the current node.
161-
162156
1. Revisit the previous node (down and to the right) to find out whether the node being remembered is a virtual base class.
163-
164157
1. If the remembered node is a virtual base class, scan the list to see whether it has already been entered. If it isn't a virtual base class, ignore it.
165-
166158
1. If the remembered node isn't yet in the list, add it to the bottom of the list.
167-
168159
1. Traverse the graph up and along the next path to the right.
169-
170160
1. Go to step 2.
171-
172161
1. When the last upward path is exhausted, note the name of the current node.
173-
174162
1. Go to step 3.
175-
176163
1. Continue this process until the bottom node is again the current node.
177164
178165
Therefore, for class `E`, the order of destruction is:
179166
180167
1. The non-virtual base class `E`.
181-
182168
1. The non-virtual base class `D`.
183-
184169
1. The non-virtual base class `C`.
185-
186170
1. The virtual base class `B`.
187-
188171
1. The virtual base class `A`.
189172
190173
This process produces an ordered list of unique entries. No class name appears twice. Once the list is constructed, it's walked in reverse order, and the destructor for each of the classes in the list from the last to the first is called.
@@ -239,5 +222,5 @@ Explicitly defining a destructor, copy constructor, or copy assignment operator
239222

240223
## See also
241224

242-
[Copy Constructors and Copy Assignment Operators](../cpp/copy-constructors-and-copy-assignment-operators-cpp.md)</br>
225+
[Copy Constructors and Copy Assignment Operators](../cpp/copy-constructors-and-copy-assignment-operators-cpp.md)\
243226
[Move Constructors and Move Assignment Operators](../cpp/move-constructors-and-move-assignment-operators-cpp.md)

0 commit comments

Comments
 (0)