Dialogue # 25: getting to the point (wq translation)
"what!"
I was called after the seventh frustration within this hour. Wen Di is obviously disturbed. "Hey, friends, quiet, ok?" Her voice floating throughout. I think her reaction is much better than before.
I used to fight with Auto_PTRS. In the first few days of working for Guru, I have already taught the value of Auto_PTRS - and its unimplete trap [1]. I have been tied up by the strange ownership of Auto_Ptr. Auto_PTR uses a handover operation that disguise to copy operation. Imagine this situation: You are working on a copy machine, put your form, then press the "Copy" button. After a while, the copier gives you a copy - then send the original to the shredder. This is a good thing for auto_ptr's copy and assignment.
In any case, I am more smart and more experience, can still be in the restrictions of the shape of Auto_PTR. For example, Auto_Ptr cannot be used to accommodate pointers to array. I played a Hacking skill to wind it, by using an explicit array delete:
Auto_Ptr
// ...
DELETE [] AutoArray.Release; ()
But I regret it immediately. I can foresee a lot of dangers of this "face-to-face things" (Guru will also call it). The most important thing is, um, the selling point of Auto_PTR is to have and destroy memory; hand-made this completely breaks the original meaning of using it.
Therefore, I decided to use a vector to have an array. It is more powerful than what I need, because I don't need to dynamically change the size of the VECTOR, and it provides this feature. I actually want to be a smart pointer that automatically handles pointers and memory management, and can be used to process arrays.
"Use the Boost library, the sky," I heard the voice of Guru after you.
"Is it 'use a big game, the sky is'?" I have an shoulder of my side. "And, don't call me the sky."
"Boost is the source of energy," Guru continues in her movie line.
I have no mood today, so I interrupted her. "Well, can we do not have to play today? Bob is in the office in London, there is no newcomer to look abnormally."
She came to see, I saw her smile and shrug. "Oh, I just feel bored," she sighed. "Have you seen the smart pointers in the Boost library?"
"Well," I am swallowing, "I have not yet taken carefully to see the Boost library. How do it achieve a smart pointer?"
"There are five kinds of dexterity pointers," Guru said while sitting down. "Two single ownership of the pointer, two processing sharing ownership."
"Sharing ownership? Oh, similar to class with reference to reference?"
"It is completely correct. The smart pointer is pair, one processing points to a pointer to a single object, and another handle pointing to the array." When it is said, she wrote on the whiteboard: scoped_ptr, scoped_array, shared_ptr, and shared_array..
"Only four, have you said before?" I asked.
"The remaining one is called Weak_Ptr. It is a non-possession of Shared_PTR. I will later talk about it. Scoped_ * The unspeakable pointer When they leave the living range, the automatic description is directed to the object. A proposed use is to implement PIMPL Ingredients - pointing to the implementation, "Before I ask, she hurriedly added a sentence.
"So coming ... they are as auto_ptr, right?"
"Not very icon. Scoped_ptr and scoped_array are not copied." "Unpacking? So, if I use a pointer as a member of the class -" I said on the whiteboard, I wrote:
Class T
{
Scoped_ptr
...
"- How do I achieve copy and assignment?"
"Like Auto_PTR," GURU side replied:
T (Const T & Other)
: p (New Timpl (* Other.p)
{
}
T & Operator = (const t & other)
{
Scoped_ptr
P.SWAP; (TMP)
}
"OOOKAY," I said lazily, I have already understood it. "So, when I use scoped_ptr, I must complete all the work you must do when using Auto_PTR, right? So why not use auto_ptr?"
"You can compile when using Auto_PTR, but do something wrong because of the automatically generated function. Use scoped_ptr to make it difficult to ignore copy semantics, because if you use the editor automatically generated version, the editor will refuse to compile this class. Similar Scoped_ptr cannot be used on an incomplete type. "I gave Guru's gaze in the front of the front of the car. She sighed. "Consider this situation," she said while writing:
Class SIMPLE;
SIMPLE * CREATESIMPLE ();
Void f ()
{
Auto_Ptr
Scoped_ptr
// ...
}
"In the function body, Simple is an incomplete type. If its destructor is act, it is destroyed by auto_ptr or scoped_ptr, and the result is undefined. Some compilers will be instantified Auto_PTR WARNING I do this, but not all compilers do this. Relative, scoped_ptr makes some small actions to ensure that the semantics are correct, if it is instantiated an incomplete type. "
"Oh, yes, of course," I am coming to show me understanding. " "So we should always use scoped_ptr to replace Auto_PTR, right?"
"Wrong, sorry," she said disappointed. "Auto_Ptr still has its use. Unlike Auto_Ptr, scoped_ptr No release () member - it does not abandon the ownership of the pointer. Because of this, and because scoped_ptr cannot be copied, the pointer it managed when scoped_ptr leaves the living range Always being delete. This makes scoped_ptr not applicable to places where you need to pass all ownership, such as factory. "
"Use scoped_ptr to other programmers to show your intent. It tells others, 'This pointer should not be copied outside the current range'. In contrast, Auto_PTR allows the ownership from the code space generated by the pointer, but it maintains The control of the pointer unless the transfer of ownership is completely. Of course, it is important to write an exceptional code. "
"Ah, good, I understand," I am muttered. "What is the other smart pointer you mentioned?"
"Scoped_array behavior is the same, except that it processing is an object array rather than a single object. Scoped_array provides a slightly differential access function. It doesn't have Operator * or Operator->, but it has Operator [] I believe," she Summary, "You need to be a scoped_array." "Maybe," I repay, "But I think I should know more about Shared_ * shape before I decided."
"Very sensible, my disciples ... you have been sorry, I am used to it." Guru smiled. "Yes, it is a good habit after familiar with each choice."
She pointed to Shared_PTR and Shared_Array on the whiteboard: "Shared_ * shaped dexterity pointer is a very useful tool. They are referenced by the count type pointer, which can distinguish the owner and the observer. For example, use the above Class T "
Void Sharing ()
{
Shared_ptr
Shared_ptr
// ...
}
"Two shared_ptr object points to the same T object. Reference count is now 2. Since Shared_Ptr is a reference count, the object has never been destroyed until the last Shared_PTR leaves the living range - at this time, the reference count dropped to 0.Shared_ * density pointer There is quite flexible, you can use them to accommodate incomplete type pointers. "
"I think you said, this is a bad?"
"It is very bad, if you are not careful. Shared_ * The smart pointer can be instantiated with a pointer to an incomplete type, but must specify a function or function sub-destroyed to be called when the object is owned. For example, we modify The above F function: "
Void DestroySIMPLE (Simple *);
Void f ()
{
Shared_ptr
Shared_ptr
}
"The first Shared_PTR failed because Simple is an incomplete type. The second success, because you explicitly tell Shared_PTR how to destroy this pointer.
"Because the Shared_ pointer is designed to be copied, they are fully applicable to standard containers, including Associative containers. And, on special occasions that must be forced type conversion, special type conversion operations can be defined to generate new Shared_ * shaped smart Pointer. For example, if we have a class base and the public inherited Derived, and a unrelated class, then you will encounter: "
Void g ()
{
Shared_ptr
Shared_ptr
Shared_dynamic_cast
Shared_ptr
Shared_Dynamic_cast
Try
{
Shared_ptr
Shared_polymorphic_cast
}
Catch (BAD_CAST)
{
// ...
}
}
"Also there is a shared_static_cast, for those special occasions," GURU summarizes. I have studied this function for a while. "Well, let me try to calculate what will happen. The first shared_dynamic_cast executed a Dynamic_cast on the smart pointer, returning a new dexterity pointer. What should I do if Dynamic_cast failed - what will happen on the reference count? ? "
Guru nodded with satisfaction. "In that case, the original count is not affected, and the new hard_ptr is an NULL pointer. As you speculate from the try / catch statement, Shared_PolyMorphic_cast will try to execute Dynamic_cast on the accommodated pointer. If the conversion failed It will throw BAD_CAST exceptions. "
"Wow," I am admired, "this class is really complete. It looks very good."
"Indeed," Guru agreed. "But there are things that must be known. Quote calculations are too simple and cannot detect any form of loop references. Similarly, Shared_PTR does not implement copy-on-write when any form is written, so use it to implement PIMPL It must be carefully measured when customary. "
I am deeply thought out, make sure I like it. "Hey," I asked, I still remember, "What is the weak_ptr you mentioned?"
"Ah, yes. Weak_ptr and Shared_PTRs jointly use .weak_ptr is the observer, does not affect the reference count of the shared object. The main purpose of Weak_PTR is to allow Shared_PTR to participate in the loop dependency -A reference B, b In turn refers to A. I like it It imagines the quasi-member in the club - it has no voting right, but can participate in the club meeting. "
"HMMM ..." I thought about it. "Because weak_ptr does not affect the reference count, if the club is disbanded - that is, the last Shared_Ptr leaves the living range - and this time weak_ptr is using a shared object?"
"In that case, the pointer for Weak_PTR maintenance is set to null. For NULL, no dereferencing operation, such as Operator *, Operator->, or Operator [], NULL check should be performed before the Dereferencing pointer. So, just as DEREFERENCING must perform null check before building a pointer, you must also check if the minor pointer is null. This limit applies to all the smart pointers in the Boost library. "
"Heaven, I have to remember too much thing," I said while staring while staring on the grass on a whiteboard.
"Don't worry," Guru smiled and left. "I will email the URL of your Boost library, and practice and demonstrate a small program of different pointers." She certainly said, I received her email in a few minutes. I immediately closed my eyes when I read this sentence:
"My apprentice, as before, this is the documentation in the Boost library:
[thank]
Thanks to Peter Dimov and Bjorn Karlsson for Providing Valuable Comments and Updates.
[Note]
[1] JIM HYSLOP AND HERB SUTTER. "Conversations # 1," C Report, April 2000.
[2] The most recent version of the library and documentation can also be obtained via anonymous CVS checkout from the Source Forge project Detailed instructions can be found at:..