Go The creation of C + + smart pointers

Source: Internet
Author: User

Zero sits at the table, mechanically repeating the action sequence of "Pinch, chew, swallow", with an invisible big letter on his face: I'm absent-minded. Sitting opposite to him, Solmyr, leisurely eating his lunch, maintained his well-cultivated image ——— or according to zero, the person familiar with his nature: the illusion.

"What's Up, zero?" Do you have a bad appetite? After basically filling the stomach, Solmyr felt as if he should have cared about his apprentice.

"Well, nothing, just ... Solmyr, why doesn't C + + support garbage collection? (Note: Garbage collection is a mechanism that ensures that dynamically allocated blocks of memory are automatically freed, and languages such as Java support this mechanism.) )”

Solmyr sighed, with a kind of calm eyes staring at zero: "is not on the BBS and people noisy C + + and Java which better?" And you lost the fight? I told you that the argument was boring. ”

"Uh ... Yes, Zero has to admit that ——— Solmyr's eyes, although not sharp, but somehow let zero produce a slight fear.

"And who told you that C + + does not support garbage collection?" ”

"Ah! Solmyr, aren't you kidding me? ”

"Zero you have to change the concept. I ask you, C + + does not support arrays that can dynamically change size? ”

"This ... Doesn't it look like it? ”

"What is that vector?" ”

"Uh ..."

"Supports a feature, not that it has to be added to the syntax, we can also choose to use the existing language mechanism to implement a library to support this feature." In the case of garbage collection, our task here is to ensure that each dynamically allocated block of memory can be released, that is ... ", Solmyr don't know where to find a piece of paper, a pen, wrote:

int* p = new int; 1
Delete p; 2

"That is, for each 1, we want to make sure that there is a 2 call, and that 1 and 2 must appear in pairs." Let me ask you, is there something in C + + that is guaranteed by the language itself to appear in pairs? ”

"..." Zero showed an effort to search for memory, but apparently nothing.

"A hint, related to the creation of a class. ”

Oh Constructor and destructor! ”

Correct Unfortunately, the normal pointer does not have constructors and destructors, so we have to write a class to add a layer of packaging, the simplest is like this: "

Class My_intptr
{
Public
int* m_p;

My_intptr (int* p) {m_p = P;}
~my_intptr () {delete m_p;}
};

............

My_intptr Pi (new int);
* (pi.m_p) = 10;

............

"Here we can safely use my_intptr without worrying about memory leaks: Once the PI variable is destroyed, we know that the memory block pointed to by PI.P is bound to be freed. But it would be too much trouble to access its members every time you use MY_INTPTR. To do this, you can add an overloaded * operator to this class: "

Class My_intptr
{
Private
int* m_p;

Public
My_intptr (int* p) {m_p = P;}
~my_intptr () {delete m_p;}

int& operator* () {return *m_p;}
};

............

My_intptr Pi;
*pi = 10;
int a = *PI;

............

"Does it look like my_intptr is a real pointer now?" Because of this, this technique is called smart pointers. Now I ask you, what is missing from this class? ”

Zero frown, unblinkingly, looks like a slow computer is hard to copy files on its hard drive. For a long while, Zero looked up, unsure, "is there a copy constructor and an assignment operator missing?" ”

"Tell me why." "Solmyr is obviously not going to let zero go like this.

"Because ... I remember right ... the 50 commandments (note: "Effective C + + 2/e") mentions that if your class has pointers pointing to dynamically allocated memory, then be sure to write a copy constructor and an assignment operator for it .... Because...... Otherwise, once you have assigned a value, the pointer to two objects will point to the same piece of memory. That's right! If this is the class above, this will cause the same pointer to be deleted two times! ”

Correct So how do we come to realize it? ”

"It's simple, we use memcpy to copy the contents of the memory that the target pointer is pointing to." ”

"What if our smart pointer points to an object of a class?" Note that there may be pointers in the object of the class and cannot be used with memcpy. ”

"That ... We use the copy construction method. ”

"What if our smart pointer to the object cannot copy the construction?" It may have a private copy constructor. ”

"That ...", zero, and decided to admit it honestly, "I don't know." ”

"Where's the problem, you know?" Is that you don't think of smart pointers as pointers. Imagine, if we were to assign a pointer, what would it mean? ”

"Well, I understand, in this case, you should find a way to get two smart pointers to the same object ... But Solmyr, does this mean you still have to delete the same object two times? ”

"Yes, we have to find a way to solve this problem. The good one is to maintain a reference count value for each pointer, each assignment or copy construction, the count value is added one, which means that there is one more smart pointer to the memory block, and each one of the smart pointer is destroyed, the count value is reduced by one, which means that the smart pointer to the memory block is a little ; Once the count value is 0, the memory block is freed. Like this: "

Class My_intptr
{
Private
int* m_p;
int* M_count;

Public
My_intptr (int* p)
{
m_p = p;
M_count = new int;

Initialization count value is 1
*m_count = 1;
}
My_intptr (const my_intptr& RHS)//copy constructor
{
m_p = rhs.m_p; Point to the same piece of memory
M_count = Rhs.m_count; Use the same count value
(*m_count) + +; Count Value plus 1
}
~my_intptr ()
{
(*m_count)--; 1 reduction in count value
if (*m_count = = 0)//There is no other pointer pointing to the memory block.
{
Delete m_p;
Delete M_count;
}
}

my_intptr& operator= (const my_intptr& RHS)
{
if (m_p = = rhs.m_p)//First determine if you are pointing to the same memory block
return *this; Yes then return directly

(*m_count)--; The count value is reduced by 1 because the pointer no longer points to the original memory block.
if (*m_count = = 0)//There is no other pointer pointing to the original memory block
{
Delete m_p;
Delete M_count;
}

m_p = rhs.m_p; Point to the same piece of memory
M_count = Rhs.m_count; Use the same count value
(*m_count) + +; Count Value plus 1
}

............
};

"The rest of the section doesn't change much, I don't bother anymore." Now imagine how we can use this smart pointer? , Solmyr put down the pen, again picked up chopsticks, some regret to find his love to eat meat balls have been cold.

Zero imagines, a little hesitant. "We ... You can use the new int expression as a constructor parameter to construct a smart pointer, and then ... Then we can arbitrarily assign, "he began to grasp the idea, the more he said faster," arbitrary with the existing smart pointer to construct a new smart pointer, the smart pointer assignment operator, copy constructor and destructor will ensure that the count value is always equal to the number of smart pointers to the memory block. Zero seemed to understand what he saw and began to get excited: "Then once the count value is 0 The allocated memory block will be released!" Other words...... There is a pointer to the memory block, it is not released, once it is not, it is automatically released! That's great! As long as we start the correct initialization of the smart pointer, we can use it like a normal pointer, and don't worry about memory release at all! That's great! Zero excited shout: "This is garbage collection!" Solmyr! We implemented a garbage collector at the dinner table! ”

Solmyr obviously did not share the excitement of zero: "I am eating, can you not shout ' a garbage collector on the table to achieve this kind of disgusting words?" "After a meal, Solmyr, with his signature bad laugh, said in a hateful tone," and please pay attention to your own image. ”

Well "Zero back to God, and found that he did not know when to stand up, and the whole restaurant in the people are watching him, hey, laugh, it makes him feel like a fool."

Zero red face sat down, lowered the voice asked Solmyr: "But Solmyr, this is really a garbage collection mechanism Ah, as long as we change this class to ... Well...... Change to a template class, like this: "Zero grabbed the paper and pen, wrote:

Template <typename t>
Class My_ptr
{
Private
t* m_p;
int* M_count;
............
};

"Wouldn't it be possible to support any type of pointer?" We can use it anywhere. ”

Solmyr shook his head: "No, you think the problem is too simple." For simple types, this class can really work well, but the reality is complicated. Consider a typical case where class Derived is a derived class of class Base, and we want to assign this value: "

base* PB;
Derived PD;
............
PB = PD;

"You know, how do you use the smart pointer above to handle this?" ”

"...", Zero is silent.

"It's not easy to implement a complete garbage collection mechanism because there are a lot of details to consider. "Solmyr began to summarize," but the basic idea is that. Thankfully, there is now a fairly mature ' reference count ' smart pointer, boost::shared_ptr. In most cases, we can use it. In addition to smart pointers, there are also some techniques that can help us avoid the problem of freeing memory, such as a memory pool. However, the key is ——— "

Solmyr again with that calm eye staring at zero:

"As a C + + programmer, you have to be creative. The kind of person who lies in the language mechanism does not think enterprising, the kind of person who must rely on grammar to know how to program, the kind of person who has no one to tell him what to do, is not suitable for the language. ”

Go The creation of C + + smart pointers

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.