[11] Destructor (Part of C FAQ Lite, Copyright © 1991-2001, Marshall Cline, Cline@parashift.com)
体,, nicrosoft @ sunistudio.com (East day production room, East day document)
FAQS in section [11]:
[11.1] What is the destructor? [11.2] What is the order of local object sectors? [11.3] What is the sequence of objects in arrays? [11.4] Can I override the designer of class? [11.5] Can I explicitly call a sectoral function on local variables? [11.6] If I want a partial object to be destructed before it is created, if I really want this, can I call its destructor? [11.7] Good, good; I don't explicitly call the destructor of the local object; but how to deal with the above situation? [11.8] If I can't wrap the partial objects in the artificial block, what should I do? [11.9] If I assign an object with a New, can I explicitly call the destructor? [11.10] What is "Placement New", why do you use it? [11.11] When writing a destructive function, do you need to explicitly call the destructive function of the member object? . [11.13] Is it possible to throw an exception when an error is detected?
[11.1] What is the destructor?
The destructor held a funeral for objects.
The destructor is used to release the resources allocated by the object. For example, the LOCK class may lock a semaphore, then the destructor will release the amount of signal. The most common example is that when New is used in the constructor, the destructor uses Delete.
The destructor is a member function of "preparing for the post". Often abbreviations become "DTOR".
[TOP | BOTTOM | Previous Section | Next Section]
[11.2] What is the order of local object sectors?
And constructor reset: first construct, followed by posture.
In the following example, the destructuring function of B will be executed first, then the destructor of A:
Void Usercode () {Fred A; Fred B;
// ...
}
[TOP | BOTTOM | Previous Section | Next Section]
[11.3] What is the sequence of objects in arrays?
And constructor reset: first construct, followed by posture.
In the following example, the sequence of the designer is A [9], A [8], ..., A [1], A [0]:
Void usercode () {fred a [10];
// ...
}
[TOP | BOTTOM | Previous Section | Next Section]
[11.4] Can I override the designer of class?
Not.
Fred classes can only have one destructor. It can only be fred :: ~ fred (). Do not return anything, don't return anything (the translation: Void is not line).
Since you don't explicitly modulate the destructor (yes, never), no matter how you cannot pass parameters.
[TOP | BOTTOM | Previous Section | Next Section]
[11.5] Can I explicitly call a sectoral function on local variables? No!
The destructor is called again at the} of the code block of the partial object. This is guaranteed by the language; There is no way to stop it. But twice calling the sect of the same object, you get the bad results! boom! You are finished!
[TOP | BOTTOM | Previous Section | Next Section]
[11.6] If I want a partial object to be destructed before it is created, if I really want this, can I call its destructor?
No! [See the previous FAQ
].
Suppose the role of the destructor File object is to close the file. Now assume that you have a File class object F, and you want File F to be closed before the scope of F object (that is,}) before:
Void Somecode () {file f;
// ... [These code is performed when f open] ...
// <- I hope to close the f here
// ... [These code is executed after f is closed] ...
}
There is a simple solution for this issue. But now please remember: Don't explicitly call the destructor!
[TOP | BOTTOM | Previous Section | Next Section]
[11.7] Good, good; I don't explicitly call the destructor of the local object; but how to deal with the above situation?
[See the previous FAQ for details
].
As long as the length of life of the local object is wrapped in a human {...} block:
Void somecode () {{file f;
// ... [These code is performed when f open] ...
}
// ^ - F destructor is automatically called here!
// ...
These codes are executed after f
] ...
}
[TOP | BOTTOM | Previous Section | Next Section]
[11.8] If I can't wrap the partial objects in the artificial block, what should I do?
Most of the time, you can limit its lifetime by wraping local objects in human {...} blocks. However, if some reasons cannot be done so, add a member function of analog paratony function. But don't call the destructor itself!
For example, in the case of a File class, a close () method can be added. A typical destructor is just calling a close () method. Note that the Close () method requires a tag file object so that the subsequent call will not close a shutdown file again. For example, a filehandle_ data member can be set to -1, and check if FileHandle_ is equal to -1 at the beginning:
Class file {public: void close (); ~ file ();
// ...
PRIVATE: INT FILEHANDLE_;
// When and only when the file is opened, FileHandle_> = 0
}; File :: ~ file () {close ();} void file :: close () {if (filehandle_> = 0) {
// ... [Do some operations - system call to turn the file] ...
FileHandle_ = -1;}}
Note that other File methods may also need to check if FileHandle_ is -1 (that is, check if the file is turned off).
Also pay attention to any constructor that does not actually open the file, you should set FileHandle_ to -1.
[Top | Bottom | Previous Section | Next Section] [11.9] If I assign an object with a New, can I explicitly call the destructor?
It may not be possible.
Unless you place the new NEW using the location, you should delete objects instead of explicit call destructor. For example, suppose to assign an object through a typical new expression:
Fred * p = new fred ();
So, when you delete it, the destructor fred :: ~ fred () will be called:
Delete P;
// automatically call P-> ~ fred ()
Since the explicit call destructor does not release the memory allocated by the Fred object itself, do not do this. Remember: DELETE P did two things: call the destructor, recycle memory.
[TOP | BOTTOM | Previous Section | Next Section]
[11.10] What is "Placement New", why do you use it?
Location Place New (Placement New) has a lot. The easiest place is to place objects in the special location in memory. This is done by the location of the pointer parameters of the New Expression section:
#include
// must be #include this to use "Placement New"
#include "fred.h"
// Class Fred statement
Void Somecode () {char memory [sizeof (fred)];
// Line # 1
Void * Place = MEMORY;
// Line # 2
Fred * f = new (place) fred ();
// Line # 3 (see "Danger" below)
// the Pointers f and Place Will Be Equal
// ...
}
Line # 1 creates an array of sizeof (FRED) bytes in memory, enough to put down the Fred object. Line # 2 Created a PLACE pointer to this memory (experienced C programmer) This step is redundant, just in order to make the code more obvious). Line # 3 is essentially called constructor fred :: fred (). The Modifier in the Fred constructor will be equal to Place. Therefore, the returned F will be equal to Place.
Recommendation: If you don't have to use the "Placement New" syntax. Only use it when you really care about the specific location in memory. For example, your hardware has a memory image I / O timer device, and you want to place a clock object in that memory location.
DANG: You have to bear such responsibility alone, the memory area points to the pointer to the "Placement New" operator must be large enough, and may need to be bounded to the object created. There is no attempt to check if you do correct when compiler and runtime system. If the Fred class needs to adjust the boundary to 4 bytes, and if the location you provide, you will make a serious disaster (if you don't understand the meaning of "boundary adjustment", don't use Placement New grammar).
You also have the responsibility of the object that is placed. This is done by explicitly calling the destructor:
Void Somecode () {char memory [sizeof (fred)]; void * p = memory; fred * f = new (p) fred ();
// ...
f-> ~ fred ();
// Decode the destructor of the object of the object to be placed}
This is the only timing of explicit call destructor.
[TOP | BOTTOM | Previous Section | Next Section]
[11.11] When writing a destructive function, do you need to explicitly call the destructive function of the member object?
Do not! Never need to explicitly call the destructor (in addition to the location of the NEW).
The destructor of the class (regardless of whether you explicitly define) automatically call the destructor's destructor. They are destructed in the order of the order in the class declaration.
Class Member {public: ~ member ();
// ...
}; Class Fred {public: ~ fred ();
// ...
Private: Member X_; Member Y_; MEMBER Z_;}; Fred :: ~ Fred () {
// The compiler automatically calls Z_. ~ Member ()
// The compiler automatically calls y_. ~ Member ()
// The compiler automatically calls x_. ~ Member ()
}
[TOP | BOTTOM | Previous Section | Next Section]
.
Do not! Never need to explicitly call the destructor (in addition to the location of the NEW).
The sect function of the derived class (regardless of whether you explicitly define) automatically call the destructor of the base class sub-object. The base class is destructed after the member object. In the case of multiple inheritance, the direct base class is destructed in the order of the order in the inheritance list.
Class Member {public: ~ member ();
// ...
}; Class base {public: Virtual ~ base ();
// Vocabulary function
// ...
}; Class Derived: Public Base {public: ~ derived ();
// ...
Private: member x_;}; derived :: ~ derived () {
// The compiler automatically calls x_. ~ Member ()
// Compiler automatically calls Base :: ~ base ()
}
Note: The sequential correlation of virtual inheritance is changeable. If you rely on its sequential correlation in a virtual inheritance level, you need more information than this FAQ.
[TOP | BOTTOM | Previous Section | Next Section]
[11.13] Is it possible to throw an exception when an error is detected?
[Recently Created (on 7/00). Click Here To Go To The Next Faq in The "Chain" of Recent Changes
]
Beware !!! See this faq for details.
.
[TOP | BOTTOM | Previous Section | Next Section]
E-mail the author [C FAQ Lite | Table of Contents | Subject Index | About The Author | © | Download Your Own Copy] Revised Apr 8, 2001