The creation of C + + smart pointers

Source: Internet
Author: User
Tags garbage collection

Turn from: http://tech.e800.com.cn/articles/2009/1224/1261633153601_1.html

Zero sitting in front of the table, mechanical repetition of "-> chewing-> swallowing" action sequence, the face with the invisible characters written: "I was absent-minded." Sitting across his solmyr, eating his lunch slowly, maintaining his always cultured image ——— or, according to zero, those familiar with his nature: illusion.

"How come zero. Do you have a bad appetite? After a basic meal, Solmyr felt that he should be concerned about his apprentice.

"Uh, nothing, just ... Solmyr, why does C + + not support garbage collection? (Note: Garbage collection is a mechanism to ensure that dynamically allocated blocks of memory are automatically freed, and languages such as Java support this mechanism.) )”

Solmyr sighed, with a calm stare at zero: "is not in the BBS and people noisy C + + and Java which is better." And I lost the fight. I told you before, this argument is boring. ”

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

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

"Ah. Solmyr, you're not joking. ”

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

"This ... I don't think so. ”

"That vector is something. ”

"Uh ..."

"Supporting a feature does not mean that it has to be added to the syntax, and we can choose to implement a library with existing language mechanisms to support this feature." In the case of garbage collection, our task here is to ensure that every memory block that is dynamically allocated can be freed, that is to say ... ", Solmyr found a piece of paper, a pen, and wrote:

int* p = new int;//1 delete p;//2

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

"...", Zero showed an effort to search the memory of the expression, but it is obvious that nothing.

"Hint, about the creation of the class. ”

Oh Constructors and destructors. ”

Right Unfortunately, the normal pointer has no constructors and destructors, so we have to write a class to add a layer of packaging, the simplest of which 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 PI is destroyed, we know that the block of memory that PI.P points to is bound to be released." But it would be too much trouble to visit 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;

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

"Now is not looking my_intptr like a real pointer anymore." Because of this, this technique is called a smart pointer. Now I ask you what is missing from this class. ”

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

"Tell me why. "Solmyr obviously don't intend to let go of zero.

"Because ... I remember the right words ... the 50 commandments (note: Referring to the book "Effective C + + 2/e") mentioned that if your class has pointers to dynamically allocated memory, be sure to write a copy constructor and an assignment operator for it ... Because...... Otherwise, once you do the assignment, the pointer to two objects will point to the same memory. That's right. If this is the class above, this will cause the same pointer to be delete two times. ”

Right So how do we make it happen? ”

"This is simple, we use memcpy to copy the contents of the memory that the target pointer points 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, not memcpy.

"That ... We use copies to construct the method. ”

"What if our smart pointer points to an object that can't copy constructs?" It may have a private copy constructor. ”

"That ...", Zero paused, and decided to confess, "I don't know." ”

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

"Well, I see, in this case, you should try to get two smart pointers to the same object ... But Solmyr, this is not still want to delete the same object two times. ”

"Yes, we have to find a way to solve this problem. One of the better is to maintain a reference count value for each pointer. Each assignment or copy construct, let the Count add one, which means that the smart pointer to the memory block is one more; every time a smart pointer is destroyed, the count value is reduced by one, which means that the smart pointer to the memory block is less than one 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; Pointing 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)--; Counting value minus 1
if (*m_count = 0)//There is no other pointer 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 it is pointing to the same block of memory
return *this; Yes, you go straight back.

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

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

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

"There's nothing much changed in the other part, I don't bother." Now imagine how we can use this smart pointer. ", Solmyr put down the pen, picked up the chopsticks again, some regret found that he loves to eat meatballs has been cold.

Zero imagined, a little hesitant. "We ... You can construct a smart pointer with the new int expression as a parameter to the constructor, and then ... And then we can arbitrarily assign the value, ", he began to grasp the idea, the more said the faster," arbitrary use of existing smart pointers to construct new smart pointers, the smart pointer assignment operator, copy constructor and destructor guarantee that the count value is always equal to the number of smart pointers to the memory block. "Zero seems to understand what he saw and started to get excited:" and then once the count is 0 the allocated memory block is 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 soon as we start the correct initialization of the smart pointer, we can use it like a normal pointer, and we don't have to worry about memory release at all. That's great. Zero excitedly shouted: "This is garbage collection." Solmyr. We implemented a garbage collector at the dinner table. ”

Solmyr obviously did not share Zero's excitement: "I'm eating, can you not shout ' at the table to achieve a garbage collector," such a turnoff. "A meal, Solmyr with his trademark bad smile, in a hateful tone said:" And please pay attention to your image. ”

Well ", Zero back to God, found that they do 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, depressed voice asked Solmyr: "But Solmyr, this is indeed 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 pen, wrote:

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

"Does it 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 does work fine, but the actual situation is very complex. Consider a typical case where class Derived is a derived class of class Base, which we want to assign: "

base* PB;

Derived PD;

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

PB = PD;

"You have to tell me how to use this smart pointer to handle this situation." ”

"...", Zero was silent.

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

Solmyr again with that calm stare at zero:

"To be a C + + programmer, you have to be creative. Those who lie on the language mechanism are not enterprising, the kind of people who have to rely on grammar coercion to know how to program, the kind of people who do not tell him what to do at a loss, not suitable for this language. ”

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.